| name | write-pipeline |
| description | Write or modify Harmont CI pipelines. Use when creating new pipelines, adding/removing steps, switching toolchains, customizing caching/triggers, or when the user asks to set up CI with Harmont. Fetches live documentation from docs.harmont.dev for up-to-date API reference. |
Write, modify, or extend Harmont CI pipelines defined in .hm/pipeline.py. Pipelines are real Python programs that import the harmont SDK and declaratively define build steps, triggers, and caching.
When to use
- The user asks to "set up CI", "add a pipeline", "write a pipeline", or "configure Harmont"
- The user wants to add, remove, or modify pipeline steps
- The user asks to add triggers, caching, or environment variables to a pipeline
- The user wants to switch toolchains or add a new toolchain to their pipeline
- The user asks to create a multi-pipeline setup
- The user is migrating from another CI system and wants a Harmont pipeline
When NOT to use
- The user only wants to run an existing pipeline — use the
validate-ci skill instead
- The user is debugging a build failure caused by their application code, not the pipeline definition
- The user asks about Harmont Cloud features (login, org management, billing)
Before you start
-
Fetch the patterns guide — the single most important reference:
WebFetch https://docs.harmont.dev/pipeline-sdk/patterns.md
Read it carefully. It covers correct vs. incorrect approaches, when to use toolchains vs. raw shell, and common anti-patterns.
-
If you need the full API reference for a specific toolchain or feature, fetch the relevant page (append .md to any docs.harmont.dev URL for raw Markdown):
- Toolchain reference:
https://docs.harmont.dev/pipeline-sdk/reference/toolchains/<name>.md (rust, python, js, go, cmake, zig, elixir, etc.)
- Chains and steps:
https://docs.harmont.dev/pipeline-sdk/reference/chains.md
- Triggers:
https://docs.harmont.dev/pipeline-sdk/reference/triggers.md
- Caching:
https://docs.harmont.dev/pipeline-sdk/reference/cache.md
- Pipeline decorator/factory:
https://docs.harmont.dev/pipeline-sdk/reference/pipeline.md
- Full page index:
https://docs.harmont.dev/llms.txt
-
If you need a complete working example for a language or framework:
WebFetch https://docs.harmont.dev/examples/<language>.md
Available examples: rust, go, cmake, zig, nextjs, python-uv, elixir
Procedure
-
Identify the project's language and build system. Look at the project root for Cargo.toml (Rust), package.json (JS/TS), pyproject.toml or setup.py (Python), go.mod (Go), CMakeLists.txt (C/C++), mix.exs (Elixir), build.zig (Zig).
-
Check for an existing pipeline. Look for .hm/pipeline.py. If none exists, run hm init --template <kind> to scaffold or write the pipeline file directly.
-
Fetch the relevant documentation (see "Before you start" above). Always fetch the patterns guide first. Then fetch the toolchain reference for the detected language.
-
Write or modify the pipeline. Follow the patterns guide strictly:
- Prefer toolchains over raw
sh() calls when a toolchain exists for the language.
- Use
.fork() for steps that can run in parallel.
- Set triggers (
push, pull_request) appropriate to the project.
- Steps run on
ubuntu:24.04 by default; set a per-step image="..." only when a specific step needs a different base.
- Set
env: {"CI": "true"} on the pipeline.
-
Validate the pipeline renders correctly:
hm render <pipeline-slug>
This outputs the v0 IR JSON. If it fails, the pipeline has a syntax or import error — fix it before proceeding.
-
Run the pipeline locally:
hm run
- Exit code 0 = pass. Inform the user.
- Exit code non-zero = fail. Read the output, diagnose, and fix. Re-run until green.
- Exit code 130 = user cancelled (Ctrl-C). Do not treat as failure.
- If Docker is not running, tell the user to start Docker.
-
If hm run fails due to what appears to be a bug in Harmont (not in the user's code or pipeline definition), and the gh CLI is available, ask the user for permission and then file an issue:
gh issue create --repo harmont-dev/harmont-cli \
--title "Bug: <concise description>" \
--body "## Environment
$(hm --version)
## What happened
<description of the unexpected behavior>
## Steps to reproduce
<pipeline snippet or steps that triggered the bug>
## Expected behavior
<what should have happened>
## Actual behavior
<error output>" \
--label bug
Important
- Always fetch documentation before writing pipelines. The SDK evolves; do not rely on memorized API surfaces. The
.md suffix on any docs.harmont.dev URL returns raw Markdown suitable for reading.
- Prefer toolchains over raw shell. The patterns guide explains why. Only use
hm.sh() / sh() for custom commands that no toolchain covers.
- Pipelines live in
.hm/pipeline.py.
hm run is the ONLY correct way to validate a pipeline locally. Do NOT try to run pipeline steps manually.
- The DSL uses decorators (
@hm.pipeline, @hm.target).
- Do NOT file GitHub issues without the user's explicit permission.