From f7f181e2ed474dfb5a45f15c4dc5189999c69202 Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 14:55:54 -0700 Subject: [PATCH 1/7] docs: overhaul README with hero, badges, vision, and community CTAs --- README.md | 265 +++++++++++++++++++++++++----------------------------- 1 file changed, 123 insertions(+), 142 deletions(-) diff --git a/README.md b/README.md index 44dd9efa..76c828b7 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,82 @@ -# harmont-cli +

+ harmont +

-[![license](https://img.shields.io/crates/l/harmont-cli.svg)](#license) +

+ Pipelines as code. Run locally in Docker. Ship to cloud when ready. +

-Run CI pipelines on your own machine, in Docker, from a Python pipeline definition checked into your repo. +

+ CI + crates.io + Discord + Slack + License +

-Define the pipeline with the [`harmont-py`](https://github.com/harmont-dev/harmont-py) DSL, then `hm run` builds a fresh container per chain, runs the steps, and reuses snapshots across runs. The same definition runs unchanged on the hosted [Harmont](https://harmont.dev) cloud via `hm cloud run`. +

+ Website · Docs · Discord · Slack +

-## Quick start +> [!WARNING] +> Harmont is in **early alpha**. Today it's a powerful local task runner — think `make` or `just`, but with Python-defined pipelines and automatic Docker isolation. The cloud CI/CD platform at [harmont.dev](https://harmont.dev) is under active development. APIs will change. We'd love your feedback — [join the Discord](https://discord.gg/hm-dev). -### 1. Write a pipeline +## What is Harmont? -Pipelines live in `.harmont/.py`. Save this as `.harmont/hello.py`: +Harmont lets you define CI/CD pipelines in Python and run them instantly on your machine in Docker containers. No YAML. No waiting for CI. Each pipeline step runs in an isolated container with automatic caching, parallel execution, and reproducible builds. ```python import harmont as hm - -@hm.pipeline("hello") -def hello() -> hm.Step: +@hm.pipeline("ci") +def ci() -> hm.Step: return ( - hm.sh("echo 'hello from harmont'", label="hello") - .sh("uname -a", label="env") + hm.sh("cargo build", label="build") + .sh("cargo test", label="test") + .sh("cargo clippy -- -D warnings", label="lint") ) ``` -### 2. Install +```sh +curl -fsSL https://get.harmont.dev/install.sh | sh +hm run ci +``` -Install the CLI from [crates.io](https://crates.io/crates/harmont-cli): +That's it. Pipeline defined in Python, executed in Docker, in two commands. + +## Highlights + +- **Python-native pipelines** — Full language, not YAML. Loops, conditionals, type checking, IDE autocomplete — it's just Python. +- **Docker isolation** — Every chain runs in a fresh container. No "works on my machine" surprises. +- **Parallel by default** — Forked chains run concurrently, bounded by `--parallelism N`. +- **Snapshot caching** — Container state is snapshotted between steps. Re-runs skip work that hasn't changed. +- **18 starter templates** — Rust, Go, Python, Java, C++, React, Next.js, and more in [`examples/`](./examples). +- **Cloud-ready** — Same pipeline definition runs on [Harmont Cloud](https://harmont.dev) with zero changes (coming soon). + +## Install + +The recommended way to install Harmont: ```sh -cargo install harmont-cli +curl -fsSL https://get.harmont.dev/install.sh | sh ``` -`hm run` also needs **Docker** and **Python 3.11+** with [`harmont`](https://pypi.org/project/harmont/): +**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) and Python 3.11+ with the Harmont DSL: ```sh pip install harmont ```
-Or build from source (contributors) +Other installation methods + +### From crates.io + +```sh +cargo install harmont-cli +``` + +### From source ```sh git clone https://github.com/harmont-dev/harmont-cli @@ -59,23 +96,52 @@ Verify: hm --version ``` -### 3. Run +## Quick Start -From the repo root: +### 1. Create a pipeline -```sh -hm run hello -``` +Save this as `.harmont/ci.py`: + +```python +import harmont as hm -The CLI walks `.harmont/*.py`, resolves the `hello` slug, renders the pipeline to JSON, and schedules chains across Docker containers. Forks run in parallel up to `--parallelism N` (default: host CPU count). +@hm.pipeline("ci") +def ci() -> hm.Step: + return ( + hm.sh("echo 'hello from harmont'", label="hello") + .sh("uname -a", label="env") + ) +``` -If the repo declares only one pipeline, the slug is optional: +### 2. Run it ```sh -hm run +hm run ci ``` -## DSL surface +If the repo declares only one pipeline, the slug is optional — just `hm run`. + +Browse the [18 example projects](./examples) for idiomatic pipelines in Rust, Go, Python, Java, C++, React, Next.js, and more. + +## Where we're headed + +**Today:** Harmont is a local task runner with Docker isolation. Define pipelines in Python, run them on your machine, get reproducible results every time. + +**Tomorrow:** The same pipelines run on [Harmont Cloud](https://harmont.dev) — managed caching, secrets, team dashboards, and zero config changes. One definition, local and cloud. + +Want to shape the roadmap? [Join the Discord](https://discord.gg/hm-dev) and tell us what you're building. + +## Community + +- **Discord** — [discord.gg/hm-dev](https://discord.gg/hm-dev) +- **Slack** — [harmont-dev.slack.com](https://join.slack.com/t/harmont-dev/shared_invite/zt-3yt0tiv7r-qHm1O0p0nVh2GU~KKhUk9A) +- **Website** — [harmont.dev](https://harmont.dev) +- **GitHub Issues** — [harmont-dev/harmont-cli/issues](https://github.com/harmont-dev/harmont-cli/issues) + +## Reference + +
+DSL surface The DSL is small. See [`harmont-py`](https://github.com/harmont-dev/harmont-py) for the full reference. @@ -88,7 +154,10 @@ The DSL is small. See [`harmont-py`](https://github.com/harmont-dev/harmont-py) | `@hm.target()` | Reusable, memoized building block | | `@hm.pipeline("slug")` | Register a pipeline (multiple per file are fine) | -## Common flags +
+ +
+Common flags ```sh hm run --parallelism 4 # cap concurrent chains @@ -99,9 +168,12 @@ hm run --no-watch # create the build and exit (don't stream events) hm run --help # full flag reference ``` -## Cloud +
+ +
+Cloud commands -`hm cloud ` talks to `api.harmont.dev`. Credentials are stored file-backed at `~/.harmont/credentials.toml` (mode `0600`); the active org slug persists under `~/.config/harmont/state/harmont-cloud.kv`. +`hm cloud ` talks to `api.harmont.dev`. Credentials are stored at `~/.harmont/credentials.toml`. | Command | What it does | |---|---| @@ -109,144 +181,53 @@ hm run --help # full flag reference | `hm cloud logout` | Forget stored credentials | | `hm cloud whoami` | Show user + active org | | `hm cloud org switch ` | Set the active organization | -| `hm cloud pipeline list` / `pipeline show ` | List or inspect pipelines | -| `hm cloud build list -p ` | List builds for a pipeline | -| `hm cloud build show -p ` / `watch -p ` / `cancel -p ` | Inspect or control a build | -| `hm cloud job list -p -b ` / `job show -p -b ` | Inspect jobs in a build | -| `hm cloud billing ` | Credit balance and usage (see below for verbs) | -| `hm cloud run [--plan-file PATH]` | Submit a pre-rendered plan JSON (defaults to `.harmont/plan.json`) | - -Source-archive upload for `cloud run` is in progress — pre-render to `.harmont/plan.json` for now. - -
-Billing verbs - -| Command | What it does | -|---|---| -| `hm cloud billing balance` | Print the current credit balance | -| `hm cloud billing transactions [--limit N]` | List billing transactions (default 100) | -| `hm cloud billing usage` | Usage over a time window | -| `hm cloud billing topup` | Top up credits | -| `hm cloud billing redeem` | Redeem a promo code | +| `hm cloud pipeline list` / `show ` | List or inspect pipelines | +| `hm cloud build list` / `show` / `watch` / `cancel` | Manage builds | +| `hm cloud job list` / `show` | Inspect jobs in a build | +| `hm cloud billing balance` / `usage` / `topup` / `redeem` | Credits and billing | +| `hm cloud run` | Submit a pipeline run to the cloud |
-## Examples - -Eighteen idiomatic starter projects live under [`examples/`](./examples). Each has a `.harmont/pipeline.py` you can read, copy, and run: - -```sh -cd examples/rust -hm run ci -``` - -Toolchains covered: Rust, Haskell, Go, Python (uv), Java/Kotlin (Gradle), C and C++ (CMake), C# (dotnet), Ruby, Perl, PHP (Composer + Laravel), OCaml, Zig, Zig+JS monorepo, and npm-based stacks (React, Next.js, TypeScript). -
-A two-branch pipeline using forks and a shared base image - -```python -import harmont as hm +Plugin authoring +`hm` is plugin-driven via [Extism](https://extism.org). Start a `cdylib` crate with the SDK: -@hm.pipeline("ci") -def ci() -> hm.Step: - setup = hm.sh( - "apt-get update && apt-get install -y curl", - label="apt", - ) - fetch = setup.fork(label="branch-a").sh( - "curl -fsSL https://example.com", - label="fetch", - ) - work = setup.fork(label="branch-b").sh( - "echo independent work", - label="other", - ) - return hm.pipeline(fetch, work, default_image="ubuntu:24.04") +```sh +cargo new --lib my-plugin +cd my-plugin +cargo add --git https://github.com/harmont-dev/harmont-cli hm-plugin-sdk ``` -
- -
-Composing larger pipelines with typed fixture-style targets - -```python -from typing import Annotated - -import harmont as hm +Implement `StepExecutor`, `SubcommandPlugin`, `LifecycleHook`, or `OutputFormatter`, declare a `PluginManifest`, and call `register_plugin!(...)`. Build to WebAssembly and install: - -@hm.target() -def apt_base(base: Annotated[hm.Step, hm.BaseImage("ubuntu:24.04")]) -> hm.Step: - return base.sh("apt-get update && apt-get install -y curl", label="apt") - - -@hm.target() -def smoke(apt_base: hm.Target[hm.Step]) -> hm.Step: - return apt_base.sh("curl -fsSL https://example.com", label="smoke") - - -@hm.pipeline("ci") -def ci(smoke: hm.Target[hm.Step]) -> hm.Step: - return smoke +```sh +cargo build --target wasm32-wasip1 --release +hm plugin install ./target/wasm32-wasip1/release/my_plugin.wasm ``` -Dependencies are resolved by parameter name from the `@hm.target` registry. `Target[T]` and `Annotated[Step, BaseImage("...")]` both unwrap cleanly under mypy and pyright. +Built-in output formatters: `human` (default), `json`. Select with `hm run --format `.
-## Build from source +## Contributing + +
+Development setup ```sh git clone https://github.com/harmont-dev/harmont-cli cd harmont-cli cargo build -cargo test # `local_*` tests need a running Docker daemon +cargo test # local_* tests need a running Docker daemon cargo clippy --all-targets -- -D warnings cargo fmt --check ``` The OpenAPI client is generated at build time from the vendored `openapi.json` via [progenitor](https://github.com/oxidecomputer/progenitor). -## Repository layout - -Cargo workspace: - -- `crates/hm/` — the `hm` binary. -- `crates/hm-plugin-protocol/`, `crates/hm-plugin-sdk/` — public API for third-party plugins. -- `crates/hm-plugin-*` — bundled plugins (Docker executor, output formatters, cloud client). -- `examples/` — sample pipeline repos to `hm run` against. - -This repo mirrors the `cli/` and `examples/` directories of the private Harmont monorepo. Open issues and PRs here; maintainers land them upstream and a CI sync replays the result back. - -## Plugin authoring - -`hm` is plugin-driven via [Extism](https://extism.org). To write one, start a `cdylib` crate and depend on the SDK: - -```sh -cargo new --lib my-plugin -cd my-plugin -cargo add --git https://github.com/harmont-dev/harmont-cli hm-plugin-sdk -``` - -Implement one of `StepExecutor`, `SubcommandPlugin`, `LifecycleHook`, or `OutputFormatter`, declare a `PluginManifest`, and call `register_plugin!(...)`. Then build to WebAssembly: - -```sh -cargo build --target wasm32-wasip1 --release -``` - -Install the resulting `.wasm`: - -```sh -hm plugin install ./target/wasm32-wasip1/release/my_plugin.wasm -``` - -Built-in output formatters: `human` (default), `json`. Select with `hm run --format `. Working examples live in `crates/hm-fixtures/src/bin/`. - -## See also - -- [`harmont-py`](https://github.com/harmont-dev/harmont-py) — the Python DSL this CLI consumes. +
## License From d4fcd7efe2b29f12d6340fd3a537b40b4747eca1 Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 15:00:14 -0700 Subject: [PATCH 2/7] =?UTF-8?q?docs:=20fix=20example=20count=20(18?= =?UTF-8?q?=E2=86=9216)=20and=20use=20static=20license=20badge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 76c828b7..29f35f78 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ crates.io Discord Slack - License + License

@@ -50,7 +50,7 @@ That's it. Pipeline defined in Python, executed in Docker, in two commands. - **Docker isolation** — Every chain runs in a fresh container. No "works on my machine" surprises. - **Parallel by default** — Forked chains run concurrently, bounded by `--parallelism N`. - **Snapshot caching** — Container state is snapshotted between steps. Re-runs skip work that hasn't changed. -- **18 starter templates** — Rust, Go, Python, Java, C++, React, Next.js, and more in [`examples/`](./examples). +- **16 starter templates** — Rust, Go, Python, Java, C++, React, Next.js, and more in [`examples/`](./examples). - **Cloud-ready** — Same pipeline definition runs on [Harmont Cloud](https://harmont.dev) with zero changes (coming soon). ## Install @@ -121,7 +121,7 @@ hm run ci If the repo declares only one pipeline, the slug is optional — just `hm run`. -Browse the [18 example projects](./examples) for idiomatic pipelines in Rust, Go, Python, Java, C++, React, Next.js, and more. +Browse the [16 example projects](./examples) for idiomatic pipelines in Rust, Go, Python, Java, C++, React, Next.js, and more. ## Where we're headed From 165823b4a8ec7a6ab2c5eaf9681bbfb033e8c961 Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 15:05:23 -0700 Subject: [PATCH 3/7] docs: use real Python toolchain example in hero section --- README.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 29f35f78..fb912bb2 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,23 @@ Harmont lets you define CI/CD pipelines in Python and run them instantly on your ```python import harmont as hm - -@hm.pipeline("ci") -def ci() -> hm.Step: +from harmont.python import PythonToolchain + +@hm.target() +def project() -> PythonToolchain: + return hm.python(path=".") + +@hm.pipeline( + "ci", + default_image="ubuntu:24.04", + triggers=[hm.push(branch="main")], +) +def ci(project: hm.Target[PythonToolchain]) -> tuple[hm.Step, ...]: return ( - hm.sh("cargo build", label="build") - .sh("cargo test", label="test") - .sh("cargo clippy -- -D warnings", label="lint") + project.test(), + project.lint(), + project.fmt(), + project.typecheck(), ) ``` @@ -42,7 +52,7 @@ curl -fsSL https://get.harmont.dev/install.sh | sh hm run ci ``` -That's it. Pipeline defined in Python, executed in Docker, in two commands. +Typed toolchains. Parallel steps. Push triggers. Real Python, not YAML — in two commands. ## Highlights From 29ecb6bd32f71f47c8ad964336cb9477c19b3b3d Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 15:06:07 -0700 Subject: [PATCH 4/7] docs: remove pip install prereq and harmont-py links (DSL is bundled) --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fb912bb2..9274bbb6 100644 --- a/README.md +++ b/README.md @@ -71,11 +71,7 @@ The recommended way to install Harmont: curl -fsSL https://get.harmont.dev/install.sh | sh ``` -**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) and Python 3.11+ with the Harmont DSL: - -```sh -pip install harmont -``` +**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) and Python 3.11+.

Other installation methods @@ -93,9 +89,6 @@ git clone https://github.com/harmont-dev/harmont-cli cd harmont-cli cargo build --release install -m 0755 target/release/hm /usr/local/bin/hm # or any dir on $PATH - -git clone https://github.com/harmont-dev/harmont-py -pip install -e ./harmont-py ```
@@ -153,7 +146,7 @@ Want to shape the roadmap? [Join the Discord](https://discord.gg/hm-dev) and tel
DSL surface -The DSL is small. See [`harmont-py`](https://github.com/harmont-dev/harmont-py) for the full reference. +The DSL is small and ships with `hm`. | Primitive | What it does | |---|---| From 18d8726ca5e31c20c7cba4684880a12c3dd0ff61 Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 15:06:40 -0700 Subject: [PATCH 5/7] docs: strip reference/cloud/plugins/contributing, point to docs site --- README.md | 91 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 9274bbb6..fdc93509 100644 --- a/README.md +++ b/README.md @@ -141,96 +141,9 @@ Want to shape the roadmap? [Join the Discord](https://discord.gg/hm-dev) and tel - **Website** — [harmont.dev](https://harmont.dev) - **GitHub Issues** — [harmont-dev/harmont-cli/issues](https://github.com/harmont-dev/harmont-cli/issues) -## Reference +## Documentation -
-DSL surface - -The DSL is small and ships with `hm`. - -| Primitive | What it does | -|---|---| -| `hm.sh(cmd, label=...)` | Start a chain with one shell command | -| `.sh(cmd, label=..., cwd=...)` | Chain another command; shares container state with the parent | -| `.fork(label=...)` | Branch a shared base into parallel work | -| `hm.wait()` | Explicit synchronization barrier | -| `@hm.target()` | Reusable, memoized building block | -| `@hm.pipeline("slug")` | Register a pipeline (multiple per file are fine) | - -
- -
-Common flags - -```sh -hm run --parallelism 4 # cap concurrent chains -hm run --env FOO=bar # inject env vars -hm run --dir path/to/source # run against a different source root -hm run --format json # machine-readable event stream -hm run --no-watch # create the build and exit (don't stream events) -hm run --help # full flag reference -``` - -
- -
-Cloud commands - -`hm cloud ` talks to `api.harmont.dev`. Credentials are stored at `~/.harmont/credentials.toml`. - -| Command | What it does | -|---|---| -| `hm cloud login` | Browser-loopback OAuth (`--paste` to paste a token) | -| `hm cloud logout` | Forget stored credentials | -| `hm cloud whoami` | Show user + active org | -| `hm cloud org switch ` | Set the active organization | -| `hm cloud pipeline list` / `show ` | List or inspect pipelines | -| `hm cloud build list` / `show` / `watch` / `cancel` | Manage builds | -| `hm cloud job list` / `show` | Inspect jobs in a build | -| `hm cloud billing balance` / `usage` / `topup` / `redeem` | Credits and billing | -| `hm cloud run` | Submit a pipeline run to the cloud | - -
- -
-Plugin authoring - -`hm` is plugin-driven via [Extism](https://extism.org). Start a `cdylib` crate with the SDK: - -```sh -cargo new --lib my-plugin -cd my-plugin -cargo add --git https://github.com/harmont-dev/harmont-cli hm-plugin-sdk -``` - -Implement `StepExecutor`, `SubcommandPlugin`, `LifecycleHook`, or `OutputFormatter`, declare a `PluginManifest`, and call `register_plugin!(...)`. Build to WebAssembly and install: - -```sh -cargo build --target wasm32-wasip1 --release -hm plugin install ./target/wasm32-wasip1/release/my_plugin.wasm -``` - -Built-in output formatters: `human` (default), `json`. Select with `hm run --format `. - -
- -## Contributing - -
-Development setup - -```sh -git clone https://github.com/harmont-dev/harmont-cli -cd harmont-cli -cargo build -cargo test # local_* tests need a running Docker daemon -cargo clippy --all-targets -- -D warnings -cargo fmt --check -``` - -The OpenAPI client is generated at build time from the vendored `openapi.json` via [progenitor](https://github.com/oxidecomputer/progenitor). - -
+For the full DSL reference, cloud commands, plugin authoring, and more — see the [docs](https://harmont.dev/docs). ## License From 83613f86101b1b819e7751ceaba8571f25583d83 Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 16:00:10 -0700 Subject: [PATCH 6/7] fix readme --- README.md | 124 +++++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index fdc93509..0eee1336 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,19 @@

> [!WARNING] -> Harmont is in **early alpha**. Today it's a powerful local task runner — think `make` or `just`, but with Python-defined pipelines and automatic Docker isolation. The cloud CI/CD platform at [harmont.dev](https://harmont.dev) is under active development. APIs will change. We'd love your feedback — [join the Discord](https://discord.gg/hm-dev). +> Harmont is in **early alpha**. Today it's a powerful local task runner — +> think `make` or `just`, but with Python-defined pipelines and automatic +> Docker isolation. The cloud CI/CD platform at +> [harmont.dev](https://harmont.dev) is under active development. APIs will +> change. We'd love your feedback — [join the +> Discord](https://discord.gg/hm-dev). ## What is Harmont? -Harmont lets you define CI/CD pipelines in Python and run them instantly on your machine in Docker containers. No YAML. No waiting for CI. Each pipeline step runs in an isolated container with automatic caching, parallel execution, and reproducible builds. +Harmont lets you define CI/CD pipelines in Typescript/Python and run them +instantly on your machine in Docker containers. No YAML. No waiting for CI. No +`commit -m "run ci" --allow-empty` spam. Each pipeline step runs in an isolated +container with automatic caching, parallel execution, and reproducible builds. ```python import harmont as hm @@ -52,55 +60,16 @@ curl -fsSL https://get.harmont.dev/install.sh | sh hm run ci ``` -Typed toolchains. Parallel steps. Push triggers. Real Python, not YAML — in two commands. + -## Highlights - -- **Python-native pipelines** — Full language, not YAML. Loops, conditionals, type checking, IDE autocomplete — it's just Python. -- **Docker isolation** — Every chain runs in a fresh container. No "works on my machine" surprises. -- **Parallel by default** — Forked chains run concurrently, bounded by `--parallelism N`. -- **Snapshot caching** — Container state is snapshotted between steps. Re-runs skip work that hasn't changed. -- **16 starter templates** — Rust, Go, Python, Java, C++, React, Next.js, and more in [`examples/`](./examples). -- **Cloud-ready** — Same pipeline definition runs on [Harmont Cloud](https://harmont.dev) with zero changes (coming soon). - -## Install +## Quick Start -The recommended way to install Harmont: +### 0. Download `hm` ```sh curl -fsSL https://get.harmont.dev/install.sh | sh ``` -**Prerequisites:** [Docker](https://docs.docker.com/get-docker/) and Python 3.11+. - -
-Other installation methods - -### From crates.io - -```sh -cargo install harmont-cli -``` - -### From source - -```sh -git clone https://github.com/harmont-dev/harmont-cli -cd harmont-cli -cargo build --release -install -m 0755 target/release/hm /usr/local/bin/hm # or any dir on $PATH -``` - -
- -Verify: - -```sh -hm --version -``` - -## Quick Start - ### 1. Create a pipeline Save this as `.harmont/ci.py`: @@ -124,32 +93,73 @@ hm run ci If the repo declares only one pipeline, the slug is optional — just `hm run`. -Browse the [16 example projects](./examples) for idiomatic pipelines in Rust, Go, Python, Java, C++, React, Next.js, and more. - -## Where we're headed - -**Today:** Harmont is a local task runner with Docker isolation. Define pipelines in Python, run them on your machine, get reproducible results every time. - -**Tomorrow:** The same pipelines run on [Harmont Cloud](https://harmont.dev) — managed caching, secrets, team dashboards, and zero config changes. One definition, local and cloud. - -Want to shape the roadmap? [Join the Discord](https://discord.gg/hm-dev) and tell us what you're building. +Browse the [16 example projects](./examples) for idiomatic pipelines in Rust, +Go, Python, Java, C++, React, Next.js, and more. ## Community - **Discord** — [discord.gg/hm-dev](https://discord.gg/hm-dev) - **Slack** — [harmont-dev.slack.com](https://join.slack.com/t/harmont-dev/shared_invite/zt-3yt0tiv7r-qHm1O0p0nVh2GU~KKhUk9A) - **Website** — [harmont.dev](https://harmont.dev) -- **GitHub Issues** — [harmont-dev/harmont-cli/issues](https://github.com/harmont-dev/harmont-cli/issues) ## Documentation -For the full DSL reference, cloud commands, plugin authoring, and more — see the [docs](https://harmont.dev/docs). +For the full pipeline reference, rich examples, and more — see the +[docs](https://harmont.dev/docs). ## License -Dual-licensed under either of +The CLI is dual-licensed under either of - Apache License, Version 2.0 ([`LICENSE-APACHE`](LICENSE-APACHE)) - MIT license ([`LICENSE-MIT`](LICENSE-MIT)) -at your option. +## Motivation + +> +> The reason [I](https://github.com/markovejnovic) started this project is +> because every other CI/CD tool I've used in my life has sucked. +> +> I've worked at [Tesla](https://tesla.com), [Bun](https://bun.com), +> [Mesa](https://mesa.dev) and never did I find a CI/CD system that was easy to +> use and was also fast. +> +> At Tesla, we used [Jenkins](https://www.jenkins.io/) -- executors are finite, +> so your builds are stuck in queues. +> +> At Bun, we used [Buildkite](https://buildkite.com/) -- large shell pipelines, +> and really pricy service, and a TS SDK which is barely slightly better than +> YAMLs. +> +> At Mesa, I migrated everyone to use [BuildBuddy](https://www.buildbuddy.io/) +> and Buildkite. [Bazel](https://bazel.build/) is awesome, but the mental +> overhead required to use it is way too high. We, sadly, ended up reverting +> to plain Buildkite. +> +> I asked myself a couple questions: +> +> - **Why can't I run my CI/CD pipelines locally?** +> [act](https://github.com/nektos/act) is an awesome project, but it's +> surprisingly slow (not to the author's fault -- but rather GHA's model). +> - **Why is my CI/CD system not just a `Makefile`?** Why is there no `hal9000 +> "build my software"` command that is shared between CI/CD and pipelines. +> - **Why can't I get preview environments for Haskell, Rust, Zig or +> whatever?** Vercel does an awesome job with `next.js` preview environments, +> but there is no good way to do this for arbitrary environments. +> - **Why do we have to write YAMLs for our pipelines?** All my pipelines end +> up being [YAML documents from +> hell](https://ruuda.nl/2023/the-yaml-document-from-hell). I think we can do +> better. +> - **Why do I need `artifacts-upload` and `artifacts-download` everywhere?** +> I don't need it locally, so why do I need it in CI/CD? In other words, why +> aren't our CI/CD systems stateful? If my build scripts can write an +> `openapi.json` in the local directory, why do I need some magic to transfer +> it between individual steps? + +Harmont's goal is to answer all these questions rhetorically -- none of these +presuppositions are necessary. CI/CD _can_ be better, and that's what +[Harmont](https://harmont.dev) is -- a CI/CD that sucks a lot less. + +I quit my job at Mesa to build Harmont. At the time of writing, I have 58 days +on my H1B grace period, but I vehemently feel that CI/CD can be better -- and +that's why I'm taking this risk. From 1ec32b972637a986c4d84e66553821f7aae42e2a Mon Sep 17 00:00:00 2001 From: Marko Vejnovic Date: Mon, 25 May 2026 16:03:50 -0700 Subject: [PATCH 7/7] docs: polish motivation section wording --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0eee1336..c15196be 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ The CLI is dual-licensed under either of > so your builds are stuck in queues. > > At Bun, we used [Buildkite](https://buildkite.com/) -- large shell pipelines, -> and really pricy service, and a TS SDK which is barely slightly better than +> and really pricy service, and a TS SDK that's only slightly better than > YAMLs. > > At Mesa, I migrated everyone to use [BuildBuddy](https://www.buildbuddy.io/) @@ -141,8 +141,8 @@ The CLI is dual-licensed under either of > - **Why can't I run my CI/CD pipelines locally?** > [act](https://github.com/nektos/act) is an awesome project, but it's > surprisingly slow (not to the author's fault -- but rather GHA's model). -> - **Why is my CI/CD system not just a `Makefile`?** Why is there no `hal9000 -> "build my software"` command that is shared between CI/CD and pipelines. +> - **Why is my CI/CD system not just a `Makefile`?** Why is there no `hm run` +> command that is shared between local dev and CI/CD? > - **Why can't I get preview environments for Haskell, Rust, Zig or > whatever?** Vercel does an awesome job with `next.js` preview environments, > but there is no good way to do this for arbitrary environments. @@ -156,10 +156,10 @@ The CLI is dual-licensed under either of > `openapi.json` in the local directory, why do I need some magic to transfer > it between individual steps? -Harmont's goal is to answer all these questions rhetorically -- none of these -presuppositions are necessary. CI/CD _can_ be better, and that's what -[Harmont](https://harmont.dev) is -- a CI/CD that sucks a lot less. +Harmont's goal is to make all these questions obsolete. CI/CD _can_ be better, +and that's what [Harmont](https://harmont.dev) is -- a CI/CD that sucks a lot +less. -I quit my job at Mesa to build Harmont. At the time of writing, I have 58 days -on my H1B grace period, but I vehemently feel that CI/CD can be better -- and -that's why I'm taking this risk. +I quit my job at Mesa to build Harmont. I'm on limited time on my H1B grace +period, but I vehemently feel that CI/CD can be better -- and that's why I'm +taking this risk.