Developing
This page is for people hacking on zipx itself, not for adopting it in your repo. Start at Quick start. If you are writing an sbt plugin that sits on zipx and should contribute catalog rows, that is Extending Versions.
The root build loads zipx from source via a meta-build mirror (project/dogfood.sbt), not via publishLocal.
Dogfood layout
Same trees under modules/*/src: the green path is dogfood (project/meta-* mirrors → root loads from
source). The amber path is the publishable plugin project for Central and scripted.
project/meta-{workflow,core,syntax,cli,central,plugin}compile the samemodules/*/src/main/scalatreesShared versions for the main build live in
project/ZipxVersions.scala(Lib/Plugin/Action). The meta-build cannot import those types, so dogfood ModuleIDs stay inproject/Dependencies.scalaproject/*.sbtcannot seeproject/*.scaladirectly (sbt layering).project/project/build.sbtpullsDependencies.scala/Dogfood.scalaonto that classpath viaunmanagedSources(no symlinks)
After changing sources under modules/{workflow,core,syntax,cli,central,sbt-plugin}: reload, then zipxWorkflowGenerate if
planner output changed.
Action pins: add or bump Action vals in project/ZipxVersions.scala
(same file as Lib / Plugin). The scheduled companion applies them; locally sbt "zipxActionUpdate yes", reload, and
zipxWorkflowGenerate. Published jar defaults embed those rows via resourceGenerators (YAML in the jar, not a
committed pin file). See the Action pins docs page.
When adding a library or sbt plugin: add a Lib / Plugin val in project/ZipxVersions.scala and select it
with ZipxVersions.deps (or a named group). You do not list it a second time. If the meta-build dogfood mirror also
needs it, add the same version to project/Dependencies.scala. sbt zipxWorkflowGenerate rewrites
project/plugins.sbt and project/build.properties. zipxCheckDeps fails generate if a libraryDependencies GAV is
not in the catalog. When adding a GitHub Action pin: an Action val in the same file; bump with zipxActionUpdate.
When adding a mirrored module: add a meta* project in project/dogfood.sbt, create project/meta-<name>/, and
wire dependsOn like the existing chain.
The publishable plugin project remains for Central publish and scripted tests.
examples/monorepo is a consumer (uses
publishLocal or a released sbt-zipx, with project/ZipxVersions.scala like a real repo). It dogfoods independent
versioning: a ShipGroup for models/coreLib, a Ship for client, ZipxModver.publish, CacheEpoch.ShipCatalog.
Aggregate test still zipxWorkflowChecks it after publishLocal. The version-updates companion regenerates it via
zipxVersionUpdatesExtraSteps (ExampleCheck.companionSteps): nested .github/workflows/ is not repo-root, so the bot
can commit that ci.yml. Root dogfood stays lockstep: Aggregate ZipxCentral.release and ZipxDocs.pages,
both with JobCondition.repositoryIs("early-effect/zipx") so fork tag pushes do not publish or deploy Pages. Do not put
Ship rows on zipx-the-product.
Remote-cache live proof lives in core tests (zipx.it.RemoteCacheItSpec): plain Testcontainers for bazel-remote
plus an sbt fixture image (Docker required; failure is a clear test failure). It runs under Aggregate Verify / sbt core/testFull. Pins and Put/Get are documented under Remote cache for teams / RemoteCacheProof.
Docs site
Docs are Specular DocSpecs under docs/src/test/scala:
sbt docs/testFull # Specular DocSpecs (same gate as CI; plain docs/test can skip on sbt 2)
sbt docs/specularSite
sbt docsDev # watch: ~docs/specularPreview (rebuild + restart DocsServe)
Open http://127.0.0.1:8765/ while docsDev is running. Pages deploy on v* tags or manual
workflow_dispatch (zipxWorkflowDispatch := true) via ZipxDocs.pages in the generated workflow. Verify is skipped
on dispatch so a docs-only refresh does not re-run the full test suite. Install / chrome versions use
specularDisplayVersion (last stable tag when dynver is *-ci) so docs-only deploys do not advertise -ci
coordinates.
Status
See ROADMAP.md and AGENTS.md (verification blast radius for agents). The plugin targets sbt 2.x / Scala 3.9.0. License: Apache-2.0.