Index
zipx generates GitHub Actions from your sbt build. You keep writing build.sbt. zipx writes the
workflow, so you do not maintain a second copy in YAML.
Day one is Aggregate: parallel Verify (test, fmt, workflow-check, advisories) and a publish job on a version
tag. Add the plugin, run zipxWorkflowGenerate, commit, open a PR. zipxWorkflowCheck fails the PR if you forgot to
regenerate. Versions live in a ZipxVersions catalog you extend (Lib / Plugin / Pin / Action inbound vals, no
second list); drop MyVersions.settings in build.sbt. Multi-artifact repos add outbound Ship / ShipGroup rows
(Independent versions); zipx itself is one ShipGroup released from zipx-release.yml.
Later pages cover extra jobs (Graph, docker, deploy), packs (Central, Pages, AWS), and the local bump loop. Skip them until you need them. CI for a busy monorepo is the one to read when a large repo's CI turns slow or blocks merges. Extending Versions is for sbt plugins that sit on zipx (splice, a company catalog). If you already maintain painful CI YAML, Why zipx is the recovery story.
Guide: Why zipx → Quick start → Versions → Independent versions → Snapshots and releases → Extending Versions → Execution modes → CI for a busy monorepo → Matrix collapse → Capabilities → Custom capabilities → Composing sbt commands → Shell and steps → Verify → Affected → Caching → Remote cache for teams → From Bazel → Action pins → Dependency updates → Pin feeds → Docker and deploy → Job conditions → Validation → Packs → Settings.
Install
// project/plugins.sbt
addSbtPlugin("rocks.earlyeffect" % "sbt-zipx" % "0.22.2")Generate & check
sbt zipxWorkflowGenerate
git add .github/workflows/ci.yml .github/actions/
sbt zipxWorkflowCheck # fails CI when the committed YAML driftsVersions catalog
// project/ZipxVersions.scala
import zipx.*
object MyVersions extends ZipxVersions:
val sbt = SbtVersion("2.1.0-RC1")
val scala = ScalaVersion("3.9.0")
val zio = Lib("dev.zio", "zio", "2.1.26")
val slf4j = Lib("org.slf4j", "slf4j-simple", "2.0.18").java
def libraries = library(zio)
def service = library(zio, slf4j)
// build.sbt
MyVersions.settings
lazy val lib = project.settings(MyVersions.libraries)
lazy val service = project.settings(MyVersions.service)Action pins (optional)
# Action vals in ZipxVersions; see Action pins docs
sbt "zipxActionUpdate yes"
sbt reload
sbt zipxWorkflowGenerateDocumentation
Continue with:
- Overview
- Why zipx
- Quick start
- Versions
- Independent versions
- Snapshots and releases
- Extending Versions
- Execution modes
- CI for a busy monorepo
- Matrix collapse
- Capabilities
- Custom capabilities
- Composing sbt commands
- Shell and steps
- Verify
- Affected
- Caching
- Remote cache for teams
- From Bazel
- Action pins
- Dependency updates
- Pin feeds
- Docker and deploy
- Job conditions
- Validation
- Packs
- Settings
- Developing