/** * Decide which `release-prepare.yml` preflight test suites a `cleo release open` * dispatch may skip, from CI results GitHub already holds for the SAME commit. * * `release-prepare` re-runs the full Linux test sweep on the commit it * checks out — main's HEAD — which is the commit main's own push CI has * already tested. When that push run is green, the release-prepare shards * prove nothing new and cost ~20 minutes of the release's critical path. * Likewise the macOS shards, which moved from every main push to nightly + * release: when the nightly macOS jobs for the exact commit are green, the * release has nothing left to learn from them. * * Every decision is forwarded to the workflow with ONE commit SHA, main's * HEAD, as `verified-sha`. The workflow honours a skip only when it checked * out that same commit, so a push to main between this check and the dispatch * cannot borrow a green result from a different tree. Any failure to answer — * `gh` error, timeout, unparseable output, no run, a run still in progress — * resolves to "run the tests", never to "skip". * * T13140: the release's own HEAD is usually the merge of the release-plan PR, * whose diff (the plan file, CHANGELOG.md, `.changeset/` moves) is not code. * Main's push CI for it is green but its `Detect Changes` gate skipped every * `Unit Tests` shard, so HEAD itself never carries a tested run, and every * release re-ran the whole suite. A test result is therefore borrowed from an * ANCESTOR whose tree is test-equivalent: walking first parents from HEAD, * each step is taken only past a RELEASE-PLAN commit (every file it changes * against its parent is under `.cleo/release/`, `.changeset/` or a * `CHANGELOG.md`, see {@link isReleasePlanPath}) whose push run is green, * whose `Detect Changes` job succeeded and whose every `Unit Tests` job was * skipped, until a commit whose push run ran every Linux shard green. The * changes gate's verdict alone is not trusted for a step: unit tests also read * repo files outside its `code` filter, and this preflight was their backstop. * The walk is bounded by {@link MAX_EQUIVALENT_ANCESTORS}, the whole decision * by {@link PREFLIGHT_DEADLINE_MS}, and the commits it took are named in the * reason. For macOS, the NEWEST completed `push` or `schedule` run with macOS * jobs (ci.yml or T13143's main-push workflow, {@link MACOS_WORKFLOWS}) of any * commit on that walk decides. * * T13823: `cleo release open` usually runs seconds after the release-plan PR * merges, while main's push CI for that very commit is still queued. With * {@link PreflightSkipOptions.inFlightWaitMs} set, a queued or in-progress * push run is polled until it completes (bounded) instead of being read as * "run the tests". The run that proved the Linux shards is returned as * {@link PreflightSkipDecision.testedRunId} and forwarded as `reused-ci-run`, * which `release-prepare` re-verifies before it skips anything. Job lists are * read page by page: a ci.yml run that ran its shards has more than 100 jobs. * * Each `gh` call is bounded by {@link PREFLIGHT_CHECK_TIMEOUT_MS}. * * @task release-speed */ /** Timeout for each `gh` call made while deciding preflight skips (ms). */ export declare const PREFLIGHT_CHECK_TIMEOUT_MS = 15000; /** Workflow file whose `push` run on main carries the Linux test shards. */ export declare const MAIN_CI_WORKFLOW: "ci.yml"; /** * Most first-parent steps taken from HEAD to a commit whose push CI tested the * tree (each step through a push run CI judged test-irrelevant). Bounds `gh` * calls; a longer run of non-code commits simply runs the tests. */ export declare const MAX_EQUIVALENT_ANCESTORS = 10; /** * Overall budget for every `gh` call one decision makes (ms). A slow API can * otherwise block `cleo release open` for minutes; whatever is left when it * runs out resolves to "run the tests". */ export declare const PREFLIGHT_DEADLINE_MS = 60000; /** * How long `cleo release open` waits for a queued or in-progress push run of * {@link MAIN_CI_WORKFLOW} to finish before deciding (ms). Main CI for a * release-plan merge takes about 4 minutes; the preflight shards it can spare * take about 13 (T13823). */ export declare const PREFLIGHT_IN_FLIGHT_WAIT_MS: number; /** Poll interval while waiting for an in-flight push run (ms). */ export declare const PREFLIGHT_IN_FLIGHT_POLL_MS = 30000; /** Workflows whose `push`/`schedule` runs carry macOS test jobs (T13143's main-push workflow too). */ export declare const MACOS_WORKFLOWS: readonly string[]; /** Options for {@link decidePreflightSkips}. */ export interface PreflightSkipOptions { /** Overall budget (default {@link PREFLIGHT_DEADLINE_MS}). */ deadlineMs?: number; /** Clock (tests). */ now?: () => number; /** * Commits from `from` to `to` (T13187: how far the newest green macOS commit * is behind HEAD); defaults to `git rev-list --count` in `cwd`, null when unknown. */ commitsBehind?: (from: string, to: string, cwd: string) => number | null; /** * T13823: how long to wait for a queued or in-progress push run to complete * (default 0: an unfinished run means the tests run). Waiting time does not * count against {@link deadlineMs}. */ inFlightWaitMs?: number; /** Blocks for `ms` (tests); defaults to a synchronous sleep. */ sleep?: (ms: number) => void; } /** * A path a release-plan PR changes: the plan file, a changelog, a changeset. * Nothing a test reads (T13140 review). */ export declare function isReleasePlanPath(path: string): boolean; /** * Runs `gh ` in `cwd` with a timeout and returns stdout. Throws on a * non-zero exit or timeout. */ export type PreflightGhRunner = (args: readonly string[], cwd: string, timeoutMs: number) => string; /** * The outcome of {@link decidePreflightSkips}, forwarded to the workflow and * returned in the `cleo release open` result. */ export interface PreflightSkipDecision { /** Commit the decisions hold for and are forwarded with (main's HEAD), or `null` if unresolved. */ verifiedSha: string | null; /** * True iff main's push CI ran every Linux Unit Tests shard green for * {@link verifiedSha}, or for {@link testedSha}, an ancestor CI judged * test-equivalent (T13140). */ skipTests: boolean; /** * The commit whose push run proved the Linux shards: {@link verifiedSha} * itself, an equivalent ancestor, or `null` when the tests run. */ testedSha: string | null; /** * T13823: id of the {@link MAIN_CI_WORKFLOW} push run that proved the Linux * shards for {@link testedSha}, forwarded as `reused-ci-run`; `null` when the tests run. */ testedRunId: number | null; /** True iff every macOS job of a nightly (or push) run for {@link verifiedSha} or an equivalent ancestor succeeded. */ skipMacosTests: boolean; /** Human-readable account of both decisions (lands in the run summary). */ reason: string; } /** * Check GitHub for CI results on the dispatch branch's HEAD and decide which * `release-prepare` preflight test suites may be skipped. * * - Linux: skipped iff the newest `push` run of {@link MAIN_CI_WORKFLOW} on * `branch` for HEAD's SHA is `completed` + `success` AND its Linux * `Unit Tests` jobs exist, cover shards `1..N`, and all succeeded. A green * run whose tests CI gated off (`Detect Changes` succeeded and every * `Unit Tests` job was skipped) of a release-plan commit does not qualify by * itself; the same check then runs on its first parent, up to * {@link MAX_EQUIVALENT_ANCESTORS} steps (T13140). * - macOS: skipped iff the newest completed `schedule` or `push` run with * macOS jobs, of HEAD or a commit that walk took, has every macOS job * concluded `success`. * * Never throws: any error, or the {@link PREFLIGHT_DEADLINE_MS} budget running * out, resolves to running the suite. * * @param runGh - bounded `gh` runner (see {@link PreflightGhRunner}) * @param cwd - repository checkout the `gh` calls resolve `{owner}/{repo}` from * @param branch - the branch `workflow_dispatch` checks out (the default branch) * @param options - overall budget and clock (tests) * @returns the decision, including the SHA it is valid for * * @example * ```ts * const decision = decidePreflightSkips(runGh, projectRoot, 'main'); * if (decision.skipTests) fields.push('--field', 'skip-tests=true'); * ``` */ export declare function decidePreflightSkips(runGh: PreflightGhRunner, cwd: string, branch: string, options?: PreflightSkipOptions): PreflightSkipDecision; /** * Carry a default-branch decision over to a release-plan branch (T13825). * * The single release PR dispatches `release-prepare` on `release/plan-`, * a branch holding one commit on top of the default branch's HEAD: the plan * file and CHANGELOG.md. The workflow honours skips only for the commit it * checks out, so the decision is re-keyed to `refSha` — and its skips are kept * only when GitHub's compare shows `refSha` strictly ahead of * `decision.verifiedSha` by release-plan paths alone ({@link isReleasePlanPath}). * Anything else, or a failed compare, keeps `refSha` and drops every skip. * * @param decision - {@link decidePreflightSkips} for the default branch * @param runGh - bounded `gh` runner * @param cwd - repository checkout the `gh` calls resolve `{owner}/{repo}` from * @param ref - the plan branch name (for the reason) * @param refSha - the plan branch's HEAD commit * @returns the decision, valid for `refSha` */ export declare function retargetPreflightSkips(decision: PreflightSkipDecision, runGh: PreflightGhRunner, cwd: string, ref: string, refSha: string): PreflightSkipDecision; //# sourceMappingURL=preflight-skip.d.ts.map