Skip to main content
Version: Next

FAQ

Read the most common questions, their short answers, and links to the full details. You can ask anything not covered here on Discord.

What is a space, and why that name?​

A space groups packages that share configuration, such as build and publish commands. It is short for workspace, a familiar term in monorepo tooling for organizing related packages.

Like Go's go work command, dispat shortens "workspace" in its configuration vocabulary. It uses the other half, space, to keep names concise. See Spaces for configuration details.

What does dispat need before the first release?​

Give dispat a git repository with full history, one configuration file naming the package folders and the build and publish commands, and commits written as conventional commits. There is no runtime to install and no state file, because the tags are the whole memory. Follow the four steps in Getting started.

Why did a package I did not touch release?​

Run dispat status to see the exact cause in the reason field before anything runs. The package might share a version group with something that moved (fixed group versioning, reported as W234), or a provider's commit carried a propagation marker such as feat(core)^ (propagated from core). The third cause is a provider publishing in an earlier run where this package failed or sat out, so the current run discharges that debt (catch-up from core, reported as W193).

Why does status show fewer packages when I run it inside a package folder?​

Standing inside a package folder narrows the invocation to that package, exactly as --package does. This narrowed selection can withhold a package when its providers sit outside the selection (W230). Run dispat from the repository root for the whole plan, or pass --strict to refuse a selection that costs anything, as explained in Partial releases.

Why did my manifest move to a provider version I did not release in this run?​

This is the auto-version reconciliation pickup. When a provider releases without you, your package's next release resolves every declared range to the provider's current published version, reported as W197. Lock-file scripts under syncLock only make the lock follow the manifest, and the changelog omits the pickup because the provider's own release documented it.

Why does a changelog entry say "No changes"?​

A record entry is never empty. A release with nothing for its notes to group states its cause instead, such as a version bump keeping a version group aligned, a version set by Release-As, a channel transition, or pending work cancelled out by its own reverts. Read Records for the exact lines.

How do I run a prerelease line, and how do I end it?​

Start the train with a channel directive on a commit, where feat(core)%rc: releases 1.3.0-rc.0 and later work continues it to rc.1. End it with a transition like release(core)%rc>stable: to graduate the train and collect every prerelease entry into the one entry stable readers see. If a graduation is refused as backwards (E185), pin the graduation itself with Release-As, and check Commits for all directives.

A release failed halfway. What do I do?​

Run dispat again, because there is no repair command and no state to clean. Packages that published keep their records, while failed ones and their dependants are skipped or failed. The next run releases exactly what is still owed at the versions it was owed, labelled as catch-up, as shown in Recovering from a failed run.

Can I release only part of the monorepo?​

Pass --package, --space, or --group to narrow any command, or stand in a folder to imply the narrowing. The plan reports what the selection costs, and a split version group catches up on the next run (W231, W234). Pass --strict to turn any cost into a refusal, and read Partial releases for the full guide.

Can dispat release packages that live in different repositories?​

Yes, through one checkout that links the other repositories in as git submodules. A plan always comes from a single checkout, because there is otherwise no graph spanning the repositories and nothing to order them by.

The usual arrangement puts the configuration in a control repository, which supplies the combined graph, the shared policy, and the fleet lock. It reads history in one of two modes. By default it reads its own commits: moving a submodule forward is a commit dispat reads like any other, and the control repository holds the versions, changelogs, tags, and records. With polyrepo: true it reads each linked repository's own conventional commits and release tags instead, and each of those repositories owns its records while the control repository checkpoints the pointers afterwards. A control repository for many repositories explains both.

You can also do without the extra repository. A non-empty repository identity makes the repository a peer; its optional repositories roster names neighbours. Each peer keeps its own configuration and records, so a run started in any of them composes the whole fleet. What a release incorporated is recorded in the links themselves rather than in a checkpoint. A choreographed fleet explains it.

Can the builds of one release run on several machines?​

Yes. Configure execution with one or more worker nodes, run dispat worker on each of them, and the release delegates its build frames to them while the machine you started it on keeps the locks, the plan, the authorizations and the records. Verified build outputs travel from the node that produced them to the nodes that consume them, so a consumer reads its provider's dist without that folder ever being committed. The transport is Git alone: an orchestrator pushes coordination branches to the repository being released and a node polls it, so no worker needs an inbound network address and the pool needs no repository of its own.

It is one release either way. There is one plan, one lock set and one set of records, and a run with no worker links behaves exactly as it always did. Read Distributed execution, and its security section before sharing one signing secret across machines.

dispat needs a link to another repository's configuration and a reproducible revision of its source. Git already provides both: each .gitmodules entry describes a flat repository link with a path and URL, while the parent commit pins the source revision through a gitlink. The linked checkout contains that repository's dispat configuration.

This avoids inventing another checkout manifest and the tooling to keep it in sync. Git handles the links and pinned revisions; dispat's configuration declares which repositories participate and how their packages release. See A control repository and A choreographed fleet.

Why doesn't choreography trigger CI jobs in each repository?​

Choreography describes how repositories own their configuration and release records. Any peer can start a release, and one dispat invocation follows the links to plan and execute the combined dependency graph.

Remote job dispatch depends on the CI/CD provider: support, permissions, status reporting, and cancellation differ. It also makes a branching release harder to stop. If one job starts two others, and those start more jobs, cancelling the first job must also find and stop its descendants while accounting for anything they already published.

Keeping execution in one invocation gives dispat one place to coordinate scheduling, cancellation, locks, and recovery. Packages already published retain their release records; a later run can plan the unfinished work. The choreography CI setup needs a checkout and a command to run, without requiring remote workflow APIs.

How do I stop something from releasing?​

Use Release-As: none to hold a package without discarding anything, and Release-As: auto to resume it at everything accumulated. Write a Deletes: footer to discard one commit's record, or use cancel(scope) to erase the pending ledger for a scope. These corrections reach only work that has not shipped, because released history is never retracted, and Correcting a record covers them all.

Does dispat ever rewrite git history?​

dispat never rewrites history. It only adds a release commit, tags, and changelog entries prepended to a file. You correct wrong records forward with Edits: and Deletes: footers in new commits, so the audit trail survives its own mistakes.

Which languages and package managers does it work with?​

dispat works with any language, because a package is a folder and a stage is a shell command, so Go, npm, pnpm, Cargo, Maven, Python, Docker, and the rest all sit in one dependency graph. Native manifest rewriting covers all thirty-six formats dispat reads, from package.json, go.mod, pom.xml, Cargo.toml, *.csproj, pubspec.yaml, and compose files to the project files Unity, Godot, Unreal, Defold, and O3DE keep a version in. The replace strategy covers a version living somewhere no parser owns, such as a Gradle coordinate or a Helm chart, and the examples show one setup per ecosystem.

Why aren't scanner and writer separate command-line programs?​

They are available as dispat scanner and dispat writer. Keeping them in one binary gives developers and CI one installation, one version to pin, and one consistent command name.

Separate executables would add shell setup and version coordination: one machine might have writer, another only dispat, and scripts would need to account for both. Subcommands keep that work out of release scripts. The Go packages remain independently importable when you want to use the scanner or writer in your own program.

Can I start with one package and add more later?​

A repository with one deliverable declares one standalone packages entry and no spaces, and nothing has to be restructured when you add more later. Adding a landing page, a docs site, or an SDK is one more entry each, plus an edge if they depend on one another. The tags already published stay the baselines everything counts from, as shown in From one package to many.

Do I have to use GitHub?​

dispat only needs git, a POSIX shell, and the full history. GitHub releases are one opt-in recorder, and the composite action is one of three ways to install the binary. Read The release job on other providers for setups on GitLab CI, CircleCI, Jenkins, Buildkite, and Azure Pipelines.

How do I pin the dispat version in CI?​

Pass a version input to the GitHub action or pass --version to the install script. The container images also ship one CLI version per image tag. Both the action and the script resolve the latest stable release when you leave the version unpinned.