// ENQUEUEING PUBLISH STAGES (release 18): one stage = one job on the editor's // `publish` queue, run as a child process. // // enqueueStage(paths, req) one stage — refused (info) when the same // stage is already queued or running // enqueuePublishRun(paths, plan) a whole plan at once (Publish now, the // site page's Build & deploy) // // Each job is `runManagedCommand` over `stageCommand(paths, req)` (S1's // stageRun.ts: `tsx bin/archilyzer.ts stage …`, cwd common/), // so Cancel kills the child — and the child's tree (next build, wrangler, // docker). The queue is ONE FIFO (`publish`, concurrency 1): stages run one at // a time, beside the publish lock the child takes. // // ORDER IS ON DISK, NOT IN MEMORY: a run's builds carry `indexAfter` and its // deploys `builtAfter` (the plan sets them), and a child whose precondition is // not met when it starts exits 3 — the job ends `failed` with the sentence in // its log. That is intended: nothing here chains one job to another. One // window it leaves: a click's run (foreground) that finds the lane's index // update already QUEUED (background — behind a job on another queue's slot, // say) reuses it as `existing`, and its own build, foreground, can then start // first and end "waiting for the index update this run started". The lane // yields while any publish stage is queued, so the window is narrow; Retry // re-enqueues the build. // // The spec IS the request: `{kind: "publish-", slug: target, params: // {runId, …req}}` (`parseJobSpec` requires `slug`; there is no `channelSlug`), // which is what Retry (editor jobReplayRegistry.ts) re-enqueues from. import { getRegistry, type JobRecord } from "../jobs/registry"; import type { JobSpec } from "../jobs/jobSpec"; import { runManagedCommand, type StreamActionResult } from "../jobs/streamCommand"; import { getPaths, type Paths } from "../lib/paths"; import type { PlanSkip, PublishPlan } from "./publishPlan"; import { stageCommand } from "./stageRun"; import { STAGES, STAGE_FLAGS, deployKindOf, isStageKind, parseStageArgs, type StageRequest, } from "./stages"; import { newStampId } from "./stamps"; export const PUBLISH_QUEUE = "publish"; /** A fresh run id (one Publish now, one lane pass): `-