Batteries-included task runner for any stack
ops detects your project's stack and gives it a working set of commands, such as
build, verify and qa, with no configuration. It supports Rust, Vite, Node,
Go, Python (uv), Terraform, Ansible, Java (Maven and Gradle) and a generic
fallback. When the defaults are not enough, you define commands and command
groups once in .ops.toml and run them with themed, parallel, fail-fast output.
The same file drives your local gates, your git hooks and CI.
- Security
- Background
- Install
- Usage
- Configuration
- Documentation
- Development
- Roadmap
- Maintainers
- Thanks
- Contributing
- License
ops runs the commands in .ops.toml as written, without sanitizing them. It
uses the same trust model as make or npm run: a project's config is trusted
code, so only run ops in directories you trust. To report a vulnerability, see
SECURITY.md.
Every project needs the same few gates, like format, lint, build, test and
audit, but each stack spells them differently. Each repository also ends up
re-deriving them in a Makefile, in hook scripts and in CI. ops keeps one
opinionated definition per stack and lets a project extend it instead of
rewriting it.
- Zero config: stack detection and built-in defaults work out of the box, and
ops initscaffolds the rest. - Declarative commands: exec commands, composite groups, clones,
[extend]layers and matrix commands, all in TOML. - Scheduling: parallel groups, fail-fast, exclusive steps and nested plans, with one themed step line per command.
- Git hooks:
ops run-before-commitandops run-before-pushrun a configured gate from the installed hook. - Project insight:
ops aboutreports code statistics, crates or modules, dependencies, coverage, backlog health and build-machine state. - Backlog tasks: native
.backlogmarkdown task management, output-compatible with the Backlog.md CLI. - Extension architecture: compile-time extensions, so you can build your own
ops.
ops is written in Rust and builds on clap for CLI
parsing, indicatif for progress rendering,
rusqlite with bundled SQLite for its analytics store,
and tokei for LOC counting.
Homebrew (macOS and Linux):
brew install rsvalerio/tap/opsapt (Debian and Ubuntu, amd64 and arm64):
sudo apt update && sudo apt install -y curl gpg
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://rsvalerio.github.io/apt/public.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/rsvalerio.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/rsvalerio.gpg] https://rsvalerio.github.io/apt stable main" \
| sudo tee /etc/apt/sources.list.d/rsvalerio.list
sudo apt update && sudo apt install opsFrom a checkout of this repository:
cargo install --path crates/cliBuilding from source needs a Rust toolchain (rustup recommended). Some commands call external tools that you install separately:
- Trivy on
PATHforops sec, and so for any gate that includes it, such as this repository'sops qa - cargo-nextest and
cargo-llvm-covfor the Rust test and coverage commands - Each stack's own toolchain (
cargo,go,bun,uv,terraform, …) for that stack's default commands
Use the tool you installed with: brew upgrade ops, sudo apt update && sudo apt upgrade, or re-run cargo install --path crates/cli from an updated checkout.
Release notes are in CHANGELOG.md.
# Initialize config for your project (auto-detects stack)
ops init
# Run a command
ops build
# Run static checks, fixing nothing (ops verify-fix formats and fixes in place)
ops verify
# Run tests and quality checks
ops qa
# Add a new command interactively
ops new-command "cargo fmt --check"Run ops --help for the commands available in the current project, grouped by
category, including the ones defined in .ops.toml.
Create .ops.toml in your project root, or run ops init:
[commands.test]
program = "cargo"
args = ["test"]
[commands.verify]
commands = ["fmt", "clippy", "build"]
parallel = true
fail_fast = trueConfig merges from built-in defaults, the global ~/.config/ops/config.toml,
the local .ops.toml, .ops.d/*.toml fragments and OPS__* environment
variables, in that order. docs/configuration.md covers
extending, cloning, scheduling, exclusive steps and matrix commands.
- Configuration:
.ops.toml, extend and clone, command groups and scheduling, matrix commands - Commands: every subcommand, stack-gated commands, stack defaults and the parity matrix
- Stack command mappings: what each default command runs on each stack
- Visual components: step icons, error boxes, theme comparison
- Backlog tasks: the
ops backlogcommand reference, file format and output contracts - Releasing: automated releases from conventional commits, Homebrew and apt publishing
- Lint policy: the workspace Clippy policy and how to add an exception
The project gates itself with its own commands:
ops verify # check-only: fmt, whitespace, clippy, build, doc (ops verify-fix repairs)
ops qa # deps, test, test-doc, sec (qa needs the Trivy CLI on PATH)ops deps checks upgrades, advisories, licenses, duplicate crates, sources and
unused dependencies. It needs cargo-edit and cargo-deny; the unused-dependencies
check also uses cargo-machete when it is installed, and is skipped otherwise.
The raw cargo invocations for the format, lint, and test legs (the check,
build, deps, and sec gates have no direct cargo equivalent here):
cargo fmt
cargo clippy --all-targets --workspace -- -D warnings
cargo nextest run --workspace --all-features # nextest does not run doctests
cargo test --workspace --doc # doctestsSee CONTRIBUTING.md for the full workflow.
- Generic Python stack (non-uv: poetry, pip/setuptools, pdm, hatch)
- Per-group scheduling boundaries: "run these groups in order, but let the steps inside one group run together" (see Command groups and scheduling)
- @rsvalerio (Rodrigo Valeri)
- Backlog.md: the backlog command and
file format that
ops backlogstays compatible with - pre-commit: the trailing-whitespace and end-of-file-fixer hooks follow its exit-code contract
- Conventional Commits and Cocogitto: release automation
- cargo-dist: release builds and installers
Questions, bug reports and ideas are welcome in GitHub issues, and PRs are accepted. Commits follow Conventional Commits, because releases are cut from them. Read CONTRIBUTING.md before opening a PR. This project follows the Contributor Covenant.
Apache-2.0 © Rodrigo Valeri