Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 169 additions & 12 deletions public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,9 @@ function validateGraph(targets: Map<string, TargetBuilder>): void
const AnnounceTasks: AnnounceTasksApi
Announcement task functions for posting build status to chat platforms.

const CHECKOUT_ACTION: "actions/checkout"
The action a {@link CiCheckout} is generated from when pins are resolved.

const CONFIG_FILE: "zuke.json"
The Zuke config file name; its presence marks a repository root.

Expand All @@ -637,6 +640,9 @@ const DEFAULT_TOOLS_DIR: ".zuke/tools"
const FileTasks: FileTasksApi
Filesystem task functions for build scripts.

const HARDEN_RUNNER_ACTION: "step-security/harden-runner"
The action a {@link CiHardenRunner} is generated from when pins are resolved.

const REDACTED: "[redacted]"
The placeholder a {@link Redactor} substitutes for each secret value.

Expand Down Expand Up @@ -913,14 +919,25 @@ class CiFile
readonly provider: CiProvider
The provider this file renders for.
readonly path: string
The output path.
The output path, once resolved.
readonly explicitPath: boolean
Whether {@link path} came from the spec rather than a default.
readonly pipeline: CiPipeline
The base pipeline (pipeline-level fields, and the jobs unless fanning out).
readonly fanOut?: FanOutOptions
Fan-out options, when this file expands the build's targets into jobs.
readonly invokes?: readonly CiInvokes[]
The targets this file runs as jobs, when declared with `invokes`.
readonly pins?: CiPinResolver
Resolves pinned action references, so a SHA is stated once per repository.
get derived(): boolean
Whether this file's jobs are derived from the build rather than declared.
pipelineFor(targets: Map<string, TargetBuilder>): CiPipeline
The pipeline this file renders. With fan-out, the build's `targets` are
expanded into one job per target; otherwise the declared {@link pipeline}.
The pipeline this file renders. Jobs come from the invoked targets, or from
a full fan-out of the graph, or — failing both — from the declared
{@link pipeline}.
at(path: string): CiFile
The same file bound to `path` — used to name a file from its field.
render(): string
Render the file's YAML content (the base pipeline; fan-out is resolved at discovery).

Expand Down Expand Up @@ -2034,13 +2051,26 @@ interface CancelResult
failures: CompensationFailure[]
Compensations that threw (recorded, non-fatal).

interface CiActionRef
A pinned action reference, and the version its commit corresponds to.

The version is emitted as a trailing `# v1.2.3` comment, which is not
decoration: Dependabot reads it to know which version a pinned SHA is, and
rewrites both together when it bumps. A generated workflow that dropped it
would leave automated bumps with no version to track.

ref: string
The pinned reference, `owner/repo@<sha>`.
version?: string
The version the SHA corresponds to, e.g. `v7.0.1`.

interface CiCheckout
The repository checkout, emitted as an `actions/checkout` step after any
{@link CiHardenRunner} and before the job's own steps. Like hardening, the
pinned {@link action} reference is required.

action: string
The pinned action reference, e.g. `actions/checkout@<sha>`.
action?: CiUses
The pinned action reference. Omit it when the file supplies a `pins` resolver.
persistCredentials?: boolean
Keep the token in git config so a later step can push. Defaults to `false`:
a job that does not push should not leave a credential behind.
Expand All @@ -2063,19 +2093,58 @@ interface CiConcurrency
interface CiFileSpec
A CI configuration file declared on a build: a pipeline bound to a path.

provider: CiProvider
The provider to render for — the one field you must choose.
provider?: CiProvider
The provider to render for. Defaults to `"github"`, which is what the
`.github/workflows` default path assumes anyway.
pins?: CiPinResolver
Resolves each action's pinned reference by name, so hardening and checkout
can be requested without restating a SHA.

With a resolver, every job is hardened and checked out by default — the
prelude nearly every job needs — and a job opts out with `harden: false` or
adjusts the policy without naming the action again.
path?: string
The output path (relative to the working directory). Defaults to the
provider's conventional location (`.github/workflows/ci.yml`,
`.gitlab-ci.yml`, or `azure-pipelines.yml`).
The output path (relative to the working directory).

Defaults to the field name the file is declared on, in the provider's
conventional directory: `releaseWorkflow = cicd({...})` writes
`.github/workflows/release.yml`. A trailing `Workflow`/`Ci`/`Yaml` is
dropped, and camelCase becomes kebab-case. Recovering the name from the
field is how `target()` works too, so a workflow needs no more ceremony
than a target.

Falls back to the provider's single conventional file
(`.github/workflows/ci.yml`, `.gitlab-ci.yml`, …) when the name is not
available — a file built outside a build class.
pipeline?: CiPipeline
The pipeline to render. Defaults to a single `build` job that runs the build.
fanOut?: boolean | FanOutOptions
Fan the build's targets out into one CI job per target, wired by their
dependencies (see {@link fanOutPipeline}). `true` uses the defaults; pass
{@link FanOutOptions} to customise. When set, {@link pipeline} supplies the
pipeline-level fields (name, triggers, …) and its `jobs` are ignored.
invokes?: readonly CiInvokes[]
The targets this workflow runs — one job each, in place of hand-written
{@link CiPipeline.jobs}.

This is the intended way to declare a workflow. A job is almost entirely
implied by its target, so naming the targets is usually the whole
declaration: the id, the display name, the `./zuke <target>` command, and
the `needs:` edges between jobs all come from the build graph. Pass a
{@link CiInvocation} instead of a bare target only for what the runner
decides rather than the build — a matrix, token scopes, an egress policy.

Each job runs its target's whole subgraph in one process, exactly as
`./zuke <target>` does locally — so dependencies inside a target run
in-process and need no cache to share their output. Use {@link fanOut}
instead to give every target in the graph its own job, which does need a
remote cache.

Targets are passed as references (`this.ci`), not names, so a rename is a
compile error rather than a workflow that silently runs nothing. As with
`dependsOn`, that means the declaration must appear below the targets it
invokes — class fields initialise top-to-bottom, so a forward reference is
`undefined`. Declaring workflows last is the simplest way to satisfy it.

interface CiHardenRunner
Runner hardening, emitted as a `step-security/harden-runner` step before
Expand All @@ -2092,8 +2161,11 @@ interface CiHardenRunner
between releases. Passing it makes the pin the caller's — and lets a build
source it from wherever its bumps are automated.

action: string
action?: CiUses
The pinned action reference, e.g. `step-security/harden-runner@<sha>`.
Omit it when the file supplies a {@link CiFileSpec.pins} resolver, which is
the better arrangement: the SHA is then stated once for the repository
rather than at every use.
egress?: "audit" | "block"
`"audit"` records outbound connections; `"block"` drops everything outside
{@link allowedEndpoints}. Defaults to `"audit"` — the safe choice for a job
Expand All @@ -2104,6 +2176,58 @@ interface CiHardenRunner
name?: string
The step name. Defaults to `"Harden the runner"`.

interface CiInvocation
One job's worth of a workflow, derived from a target.

A job's shape is almost entirely implied by the target it runs: the id and
display name come from the target, the command is `./zuke <target>`, and the
`needs:` edges come from the target's `dependsOn`. So an invoked target
usually needs nothing said about it at all — pass the target and the job is
generated.

The fields here are the residue that genuinely cannot be inferred, because
they are properties of the runner rather than of the work: which OS matrix
to fan out over, which token scopes the job needs, how much egress to permit,
how long to allow. Set one only when the default is wrong.

target: TargetBuilder
The target this job runs.
id?: string
Override the job id (defaults to the target's name, CI-sanitised).
name?: string
Override the display name (defaults to the target's description, else its name).
runsOn?: string
The runner, when it differs from the pipeline default.
matrix?: Record<string, Array<string | number>>
A build matrix — fanning one target out over several OSes, say.
failFast?: boolean
Let the other matrix legs finish when one fails.
permissions?: Record<string, string>
The token permissions this job needs (see {@link CiJob.permissions}).
timeoutMinutes?: number
Fail the job after this many minutes.
harden?: CiHardenRunner | false
Harden this job's runner, overriding the pipeline default.
checkout?: CiCheckout | false
Check out in this job, overriding the pipeline default.
if?: string
A condition gating the job.
env?: Record<string, string>
Environment variables for the target's own step — where a secret is mapped
in, e.g. `{ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" }`.
after?: readonly TargetBuilder[]
Extra `needs:` edges beyond those implied by the target's `dependsOn`. Use
it to order two invoked targets that are independent in the build graph but
must not run concurrently in CI.
before?: CiStep[]
Steps to run before the target, for something no target can do (see below).
then?: CiStep[]
Steps to run after the target.
steps?: CiStep[]
Replace the generated `./zuke <target>` step entirely. The escape hatch of
last resort — prefer {@link before}/{@link then}, and prefer moving the work
into the target over either.

interface CiJob
A job: a named unit of work with steps, optionally fanned out by a matrix.

Expand Down Expand Up @@ -2155,6 +2279,11 @@ interface CiPipeline
permissions?: Record<string, string>
Workflow-level token permissions (GitHub only), e.g.
`{ contents: "read", "pull-requests": "write" }`. Ignored elsewhere.

Defaults to `{ contents: "read" }` — least privilege, and what a workflow
that only reads the repository needs. A job that needs more declares it, so
the wider scope sits next to the job that justifies it. Pass `{}` for no
permissions at all, which is stricter than the default rather than absent.
concurrency?: CiConcurrency
Limit concurrent runs (GitHub only). Ignored elsewhere.
harden?: CiHardenRunner
Expand Down Expand Up @@ -2185,7 +2314,7 @@ interface CiStep
Continue the job even when this step fails (`continue-on-error`). GitHub only.
run?: string
A shell command to run. Portable across all providers.
uses?: string
uses?: CiUses
A GitHub Action reference (e.g. `actions/checkout@v4`). Rendered only for
GitHub; skipped for GitLab and Azure.
with?: Record<string, string>
Expand Down Expand Up @@ -3373,12 +3502,25 @@ type CiHost = "github" | "gitlab" | "azure" | "bitbucket" | "local"
match {@link CiProvider} so they compose with CI generation and per-host
integrations (e.g. posting a review to the right pull-request API).

type CiInvokes = TargetBuilder | CiInvocation
A target to invoke, bare when the derived job needs no adjustment.

type CiPinResolver = (action: string) => CiUses
Resolves an action's pinned reference by name, e.g. `"actions/checkout"`.

Supplying one is what lets a workflow declare hardening and checkout by
intent rather than by repeating a SHA at every use. Without it each
{@link CiHardenRunner} and {@link CiCheckout} must carry its own `action`.

type CiProvider = "github" | "gitlab" | "azure" | "bitbucket"
The CI providers {@link generateCi} can target.

type CiSyncStatus = "written" | "unchanged" | "stale"
What {@link syncCiFiles} did to a file.

type CiUses = string | CiActionRef
A step's `uses:` value — a bare reference, or one carrying its version.

type Condition = () => boolean | Promise<boolean>
A predicate gating whether a target runs; may be synchronous or async.

Expand Down Expand Up @@ -10493,6 +10635,21 @@ interface AiReviewWorkflowSpec
the workflow drops the step, and the reviewers use their own configured base
rather than the fetched `FETCH_HEAD`. Preferable where it applies: the same
`zuke review` then works locally, where no workflow step exists to run.
hardenRunner?: string
The pinned `step-security/harden-runner@<sha>` to harden the runner with.
Defaults to a pin baked in here.

Pass it when the build sources pins from somewhere that stays current — a
generated workflow whose SHA comes from a constant in a published package is
a trap: a bot bumps the committed file, the next run regenerates it from the
stale constant, and the bump is silently reverted.

A bare `owner/repo@<sha>`, without the `# vX.Y.Z` comment the other
generated workflows carry: attaching one needs a core newer than this
package's declared floor, and Dependabot bumps a comment-less pin anyway.
Adopt the richer form once the floor moves past that release.
checkout?: string
The pinned `actions/checkout@<sha>` to check the repository out with.
path?: string
Output path. Defaults to the host's conventional location.
name?: string
Expand Down
Loading
Loading