Overview
Gleam builds, tests, and publishes one package directory at a time. Trellis
is the workspace layer on top: it fans those commands across a whole
repository and adds changelogs, versioning, and publishing, deriving its model
of the workspace from the gleam.toml files already in it.
For example, the example workspace selects packages from two directories:
[tools.trellis]members = ["packages/*", "examples/*"]Their path dependencies form this graph:
lat_core (1.2.0)lat_mid (0.5.0) └─ lat_corelat_cli (0.3.1) ├─ lat_core └─ lat_midpackage_a (0.0.0) └─ lat_cliThroughout these docs, a package is one Gleam package, a directory with
its own gleam.toml. A member is a package that belongs to the workspace;
that word appears where membership itself is the point, as in the members
key and the @members exclusion.
Derived, then verified
Section titled “Derived, then verified”The member set, its topological order, change impact, and publish order all
come from manifests that already exist. What can’t be derived has to be
duplicated somewhere: locked versions, changelogs, tags, toolchain pins.
trellis doctor checks those, exiting non-zero when one breaks.
Some findings are mechanically fixable, such as a releasable package missing
its CHANGELOG.md, or a manifest.toml locked version that drifted from its
package’s gleam.toml. For those, trellis doctor --fix writes the fix and
re-reports whatever’s left. --dry-run lists the same fixes without touching
a file.
Opinionated, but modular
Section titled “Opinionated, but modular”Trellis has one way of doing each job: change fragments are TOML files in
.changes/unreleased/, every releasable package gets its own git tag, and
version bumps are derived from fragment kinds.
The jobs themselves are independent. Every capability is a plain command, and nothing requires the piece above it, so you can adopt trellis a layer at a time:
- Just the task runner.
run,exec,list, andgraphneed no configuration at all, because members are auto-discovered from git. Keep your existing changelog tool and CI untouched. - Add changelogs and versioning. Fragments,
version plan, andversion applymanage bumps and changelogs without trellis owning your release workflow, or any CI at all. - Add publishing.
tagandpublishpush to Hex in dependency order, from your own scripts or workflows. - The full pipeline.
ci,changelog check, andrelease prturn GitHub Actions workflows into thin triggers around trellis commands.
Commands that feed automation emit structured JSON (--json, trellis ci),
so any single piece slots into whatever tooling already surrounds it, under a
versioned guarantee you can assert on.
Getting started
Section titled “Getting started”- Install trellis: a single prebuilt binary; shell installer, Homebrew, mise/asdf, or cargo.
- Configure the workspace if you need to. With no
configuration, members are auto-discovered from git; one optional
[tools.trellis]table ingleam.tomlcovers everything else. - Run
trellis doctorto verify the setup, then run tasks across the workspace.
What’s in these docs
Section titled “What’s in these docs”| Page | Covers |
|---|---|
| Installation | Install channels, pinning a version in CI, verifying the setup. |
| Configuration | The [tools.trellis] table: members, task-scoped exclusions, custom tasks, changelog and publish settings. |
| Task running | run and exec: built-in and custom tasks, graph-parallel scheduling, selecting packages with --since. |
| Changelog & versioning | TOML change fragments, PR enforcement, planning and applying version bumps. |
| Publishing | Release PRs, per-package tags, publishing to Hex in dependency order with path deps rewritten. |
| Dependency pinning | trellis pin: git dependency refs rewritten to commit SHAs, updated as a reviewable diff, checked for force-moves. |
| CI recipes | GitHub Actions shapes: affected-only matrices, PR gates, and the release pipeline. |
| JSON output | What the --json payloads guarantee: the schema field, what a stable shape permits, and where it stops. |
| Compatibility | The exit-code contract, what semver covers, and the minimum supported Rust version. |
| CLI reference | Every command, flag, and argument, generated from the CLI itself. |