Deployment modes

Sparkwing has two launch modes: Local and Sparkwing Cloud. Self-hosted runners register to Cloud. Operating a shared controller is deferred to a future licensed offering.

ModeInfrastructure you operateDashboard and historyExecution
Localnoneprivate to this OS userthis machine
Sparkwing Cloudoptional self-hosted runnersshared with your teamCloud and registered runners

LocalSection anchor link

sparkwing run starts the local controller on demand and hosts the run in the CLI process. The controller owns SQLite, logs, secrets and local object storage under ~/.sparkwing/. Its private socket checks the connecting OS user. Local mode needs no account, profile or network listener.

sparkwing run build
sparkwing dashboard start
sparkwing dashboard open

After the first successful build, exact-pinned pipelines can run offline. See Getting started.

Sparkwing CloudSection anchor link

Cloud owns shared history, the team dashboard, schedules, webhooks, credentials and the queue. Clients and self-hosted runners connect over outbound HTTPS. They hold no database or object-store credentials.

Save a member credential from stdin, then submit a pipeline:

sparkwing profiles add --controller https://api.sparkwing.example --profile work --token-stdin
sparkwing pipeline trigger build --profile work

profiles add checks public health and authenticates through /api/v1/auth/whoami. Passing the probe grants only the credential's existing authority. Read commands use the same explicit profile:

sparkwing runs list --profile work

Add --working-tree to submit an immutable snapshot of tracked and unignored untracked files. The controller stores the bundle and seals its digest. Awarded workers acquire that exact source through their claim authority.

A trigger, webhook run or schedule that selects no runner runs anywhere, on Cloud and on self-hosted controllers alike: any eligible claimant can take its plan step, generator evaluations and each job. The team's claim ranking orders the claimants, best first: here (the personal runner on the machine whose CLI started the run), personal (the requester's own machines), github-actions, self-hosted (the team's shared runners and the local controller's own queue) and cloud (the launcher; a self-hosted controller has none and refuses cloud in a ranking). A self-hosted sparkwing-controller does not run pipelines itself: until a runner is registered and online, unselected work waits with a no_eligible_runner notice. During the first 5 seconds after readiness, a job with no named runner is held for the best-ranked tier with a live claimant on the same team that matches its labels and offered a free slot in its latest poll. That claimant can take it at once. Each award consumes one advertised slot until the runner polls again. A busy or offline better tier causes no wait. After the 5-second window, any eligible claimant may take it. There is no additional grace period. The launcher takes part only while the team has credits or a saved card. A job that requires a pool=, name= or class= term skips the ranking and goes to the runners it names. Explicit Prefers placement holds still apply when a preferred claimant is allowed by the team's ranking and has a free slot. An owner offers its occupied slot for its own run's jobs, keeping the captured host labels and platform even when its last queue poll has no free slots. Preference scores do not reorder the queue.

Runs started by a push, pull request, release or schedule, and their retries and child runs, skip here and personal: a personal machine takes only its owner's manual runs.

A team administrator reorders or drops tiers. A dropped tier takes no unselected work, and none means first come:

sparkwing team settings set --profile work --claim-ranking cloud,self-hosted

App runs and App-armed schedules take their owner from the repository's App configuration (runner: anywhere | cloud | github-actions | pool=<name>, default anywhere). --runner cloud keeps a triggered run on Cloud, like the App's cloud owner. --runner NAME keeps the whole run on that self-hosted runner, --runner label=LABEL places its plan and every job on runners with that label, as does a pool route rule, and --runner here hosts it in the submitting CLI. Intake seals the choice in the run's request, so retries keep it. A run whose work nobody has claimed after 30 seconds shows a notice in sparkwing runs status. When only metered Cloud placement could take that work and the team has no credits or payment method left, the notice is credit_hold instead, naming the hold, and the launcher takes the work as soon as credits or a card arrive. Work an unmetered runner of the team could take keeps the unclaimed_work notice. When no eligible runner is online at all, the notice is no_eligible_runner and names why: a tier the ranking drops ("Cloud is off in this team's runner ranking"), a pin ("this job targets pool=gpu only"), or that no runner of the allowed tiers is online.

Self-hosted runnersSection anchor link

Enroll a machine into a Cloud team:

sparkwing runners add --profile work --runner builder

Personal capacity belongs to your own account and requires an independent account session during enrollment. Team capacity uses a team-admin credential. See Self-hosted runners.

Selecting a profileSection anchor link

A profile in ~/.config/sparkwing/config.yaml selects a controller connection. Pass --profile NAME on the command that should reach Cloud. sparkwing run uses local state. Its --sw-cache-from PROFILE and --publish PROFILE options opt into read-only remote cache access and publication separately. Pipeline binaries stay in the machine's local cache. There is no separate cache service.

When isolating runtime state with SPARKWING_HOME, set SPARKWING_CONFIG to a private config path too before saving a profile. See Storage backends and Local execution.

Advanced shapesSection anchor link

Hosted controllerSection anchor link

The repository's controller and Helm chart are Cloud operator infrastructure. The controller owns persistence and issues scoped object transfers through /data. Runners never write directly to its database. The SDK pin selects the verified matching engine, and controller APIs retain the engine's support window. Without a Cloud --limits-profile (cloud or cloud-free), unselected work runs on the team's registered runners; the controller never executes pipelines itself.

Cloud operators can create a team and its first administrator without OAuth:

sparkwing operator teams create --team support-test --display-name Support --profile deployment -o json

This requires deployment authority with operator.tokens, or the operator's direct browser session and CSRF proof. The operation returns the first team credential once. See Cloud operations and the controller chart.