Skip to main content

commoner

One front door for everything a repo can do. Test tiers, dev servers, the docker stack, migrations and the little chains of steps between them are named in a commoner.yaml — and commoner <thing> runs them.

The alternative it replaces is a scripts/ folder: fifteen four-line shell files that each cd to the repo root and exec one command, where adding a test tier means writing another one and the only way to know what a repo can do is to ls them.

pip install commoner-cli
# commoner.yaml
tests:
  unit: {marker: unit}
  e2e:
    marker: e2e
    args: --api-mode=live_server

ui:
  path: ui
  package_manager: pnpm
  tests:
    unit: {script: test}

run:
  api:
    script: uvicorn app.api:app --reload --port 8000

docker:
  path: infrastructure
  local:
    compose: compose.yaml
    profiles: {api: the API in a container}

migration-providers: [alembic]

tasks:
  init-db:
    steps: [up --detach, migrate]
commoner help                # what this repo defines — generated from the config
commoner test unit           # poetry run pytest -m unit
commoner test ui:unit        # pnpm run test, in ui/
commoner test                # everything, across every project
commoner api                 # poetry run uvicorn app.api:app --reload --port 8000
commoner up api --detach     # docker compose --profile api up --detach
commoner init-db             # compose up --detach, then alembic upgrade head
commoner --dry-run <any>     # print the commands, run nothing

Nothing above is built in. unit, api, init-db and the rest exist because the config names them; the tool only knows how to run a kind of thing.

The config

Top-level keys are either a known section or a projectui: is a project because it isn't reserved. example.commoner.yaml is the annotated schema; the short version:

Section What it defines
project the repo's name, for help output
python the root project's toolchain: runner (poetry/uv/none), install_args, tests_path
tests test tiers, as commoner test <tier>
run long-lived processes; each is also a top-level command
docker one compose file and its profiles, as commoner up [profile...]
migration-providers gives you commoner migrate / commoner revision
tasks a named sequence of other commoner commands
env the env file commoner bootstrap creates from its example
anything else another project, with its own path and package manager

What an entry runs

Every entry — a tier, a process, a step — says what to run in exactly one of four ways, and where with project::

unit:    {path: unit}                # <runner> pytest tests/unit
unit:    {marker: unit}              # <runner> pytest -m unit    (module: also works)
unit:    {script: pytest -m unit}    # through the project's runner / package manager
unit:    {cmd: poetry run pytest}    # literally, as written

Plus args: (always appended, before the caller's own), description: (shown in help), and todo: (say it isn't built yet and skip, rather than fail).

Extra arguments on the command line are appended to whatever the entry resolves to, so the "$@" you would write in a shell script is implicit — and stripped if you write it anyway. commoner test e2e -k login and commoner test ui:e2e --tags '@auth' both land where you expect.

Conventions worth knowing

  • A tier named all stands in for its whole project, so commoner test is one pytest run rather than one per marker.
  • A node project with no node_modules makes its tiers skip, not fail — a partial checkout stays testable.
  • Unprofiled compose services always come up; profiles layer the rest on top. commoner up is your backing services, commoner up api workers the lot.
  • Names in run: and tasks: become top-level commands, and the config is rejected if one shadows a built-in.

Built-in commands

Command What it does
bootstrap install every project's dependencies, create the env file
test [tier] [args...] run a tier, a project's tiers, or everything
run <name> [args...] run a configured process
up [profile...] / down the docker stack
build build the configured dockerfile
compose <args...> raw docker compose against the stack
migrate [target] / revision <message> the configured migration provider
help the repo's own command surface

Global flags: --config PATH, --dry-run, -q/--quiet, --version.

How it works

  • config.py — the only module that knows the file format: loading, validation, and turning an entry into an argv.
  • cli.py — the dispatcher. Help text is generated from the config, so it can't drift from it.
  • process.py — how a command leaves the process: exec_ hands over the terminal (signals, exit codes and Ctrl-C belong to the real command), run waits. A multi-step caller sets Console.replace = False, which turns the former into the latter for everything nested under it — so a command written to hand over still composes inside a task.
  • commands/ — one module per built-in; migrations/ — one per provider.

A project is a unit of source with its own toolchain: it knows how to install itself, how to prefix a command so it runs in its environment, and when it isn't ready.

Wiring it into a repo

Installing puts commoner on your PATH. Many repos also keep a one-line dev shim at the root so a fresh clone needs no explanation:

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
exec commoner "$@"

Status

Early. The schema is settled enough to use and documented in example.commoner.yaml; alembic is the only migration provider so far, and new kinds of thing are the only reason to change the code — a new entry point is a yaml edit.

MIT licensed.

Release files for commoner-cli 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for commoner-cli 0.1.0
File Size Uploaded
commoner_cli-0.1.0.tar.gz 18.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for commoner-cli 0.1.0
File Interpreter ABI Platform
commoner_cli-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.8 kB

Release files / commoner_cli-0.1.0.tar.gz

Download URL commoner_cli-0.1.0.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0ede430d3d41e5bf3e1b294b39abff2fb02ab95fb57c05b5e79259aef809dded
BLAKE2b-256 checksum
How to use checksums
e12fa2cbfb1d008c1b0f1b68644c6cd72a8e4c9515e21ca14ff207dacff2442f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release files / commoner_cli-0.1.0-py3-none-any.whl

Download URL commoner_cli-0.1.0-py3-none-any.whl
Size 22.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af0a74079f8627119d11797641c5dd8066dedc1f863e5a496047c3d292e4eb4b
BLAKE2b-256 checksum
How to use checksums
5b1bcb5d168367d687c62c4d2d3dd4698239075a41f2abb6a35ee7e6990eaea0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page