Skip to content

Commit d1a89b2

Browse files
docs: add CONTRIBUTING.md and CODE_OF_CONDUCT.md (#160)
1 parent baf0740 commit d1a89b2

3 files changed

Lines changed: 324 additions & 0 deletions

File tree

CODE_OF_CONDUCT.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
6+
7+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8+
9+
## Our Standards
10+
11+
Examples of behavior that contributes to a positive environment for our community include:
12+
13+
* Demonstrating empathy and kindness toward other people
14+
* Being respectful of differing opinions, viewpoints, and experiences
15+
* Giving and gracefully accepting constructive feedback
16+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17+
* Focusing on what is best not just for us as individuals, but for the overall community
18+
19+
Examples of unacceptable behavior include:
20+
21+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
22+
* Trolling, insulting or derogatory comments, and personal or political attacks
23+
* Public or private harassment
24+
* Publishing others' private information, such as a physical or email address, without their explicit permission
25+
* Other conduct which could reasonably be considered inappropriate in a professional setting
26+
27+
## Enforcement Responsibilities
28+
29+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
30+
31+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
32+
33+
## Scope
34+
35+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
36+
37+
## Enforcement
38+
39+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at marko@harmont.dev. All complaints will be reviewed and investigated promptly and fairly.
40+
41+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
42+
43+
## Enforcement Guidelines
44+
45+
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
46+
47+
### 1. Correction
48+
49+
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
50+
51+
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
52+
53+
### 2. Warning
54+
55+
**Community Impact**: A violation through a single incident or series of actions.
56+
57+
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
58+
59+
### 3. Temporary Ban
60+
61+
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
62+
63+
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
64+
65+
### 4. Permanent Ban
66+
67+
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
68+
69+
**Consequence**: A permanent ban from any sort of public interaction within the community.
70+
71+
## Attribution
72+
73+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
74+
75+
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
76+
77+
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
78+
79+
[homepage]: https://www.contributor-covenant.org
80+
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
81+
[Mozilla CoC]: https://github.com/mozilla/diversity
82+
[FAQ]: https://www.contributor-covenant.org/faq
83+
[translations]: https://www.contributor-covenant.org/translations
84+

CONTRIBUTING.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Contributing to Harmont
2+
3+
Thank you for your interest in making Harmont better — we're glad you're here.
4+
Contributions of every size are valued, whether that's a typo fix, a bug
5+
report with a great reproduction, or a new feature. This document explains how
6+
we work together, how to get your environment running, and how to get a change
7+
merged.
8+
9+
If you just want to chat or ask a question, join us on
10+
[Discord](https://discord.gg/hm-dev) or
11+
[Slack](https://join.slack.com/t/harmont-dev/shared_invite/zt-3yt0tiv7r-qHm1O0p0nVh2GU~KKhUk9A).
12+
13+
## Finding something to work on
14+
15+
- Issues labeled [`good first issue`](https://github.com/harmont-dev/harmont-cli/labels/good%20first%20issue)
16+
are scoped for newcomers.
17+
- Issues labeled [`help wanted`](https://github.com/harmont-dev/harmont-cli/labels/help%20wanted)
18+
are ready for anyone to pick up.
19+
- Found a bug? [File an issue](#filing-issues) — a good bug report is a
20+
first-class contribution on its own.
21+
22+
## Before you write code: open an issue
23+
24+
**Every pull request must reference an issue that a maintainer has agreed
25+
should be fixed or built.** This applies to small fixes too — an issue takes
26+
two minutes to file and it means nobody's work gets wasted on a change we
27+
can't merge or that someone else is already making.
28+
29+
The flow is:
30+
31+
1. Open an issue (or comment on an existing one) describing the bug or the
32+
feature and how you'd like to approach it.
33+
2. Wait for a maintainer to confirm the direction. For bug fixes this is
34+
usually quick; for features expect some design discussion first — a new
35+
feature is a long-term maintenance commitment, so we want consensus before
36+
anyone invests time in code.
37+
3. Comment that you're taking it, then go build it.
38+
39+
Pull requests for features that were never discussed in an issue will
40+
usually be closed with a pointer back to this section. It isn't personal —
41+
it's how we protect both your time and ours.
42+
43+
You can expect a first response on issues and PRs within a week. If you
44+
haven't heard anything by then, feel free to ping the thread.
45+
46+
## Use of AI
47+
48+
AI-assisted contributions are welcome — much of Harmont is built with AI in
49+
the loop. The requirement is that **you** understand and stand behind what
50+
you submit: you can explain the change, you've run the tests, and the PR
51+
description is written (or at minimum, curated) by you. Please keep
52+
descriptions concise and specific; a giant auto-generated summary suggests
53+
the author doesn't know what the change does, and PRs that show no human
54+
understanding will be closed.
55+
56+
## Setting up your environment
57+
58+
Prerequisites:
59+
60+
- **Rust** — latest stable via [rustup](https://rustup.rs). The workspace
61+
uses edition 2024, so you need a recent stable (1.85+). Formatting is
62+
pinned to **rustfmt 1.96** in CI; if your local `cargo fmt` produces
63+
unrelated diffs, update your toolchain (`rustup update stable`).
64+
- **Docker** — a running daemon. The local execution backend runs every
65+
pipeline step in a container, and the integration tests do too. On Linux,
66+
the layer-caching snapshotter also needs FUSE's `user_allow_other` enabled
67+
in `/etc/fuse.conf`.
68+
- **Python 3.11+** and [uv](https://docs.astral.sh/uv/) — for the `harmont`
69+
pipeline DSL that lives in `crates/hm-dsl-engine/harmont-py/`. Linting is
70+
pinned to **ruff 0.15** in CI.
71+
72+
Build everything from the workspace root:
73+
74+
```sh
75+
cargo build
76+
```
77+
78+
Run your freshly built CLI against a real project — the `examples/`
79+
directory has fourteen runnable projects to try it on:
80+
81+
```sh
82+
cargo run -p harmont-cli -- run ci --backend docker --dir examples/rust
83+
```
84+
85+
## Running the checks
86+
87+
CI runs the same checks you can run locally. Before pushing, this block
88+
should pass from the workspace root:
89+
90+
```sh
91+
cargo test --workspace --locked
92+
cargo fmt --all --check
93+
cargo clippy --workspace --all-targets --locked -- -D warnings
94+
```
95+
96+
And for the Python DSL, from `crates/hm-dsl-engine/harmont-py/`:
97+
98+
```sh
99+
uv sync --all-extras
100+
uv run pytest -v
101+
uv run ruff format --check .
102+
uv run ruff check .
103+
uv run ty check harmont
104+
```
105+
106+
Two things that surprise people:
107+
108+
- **Clippy is strict.** The workspace flags `unwrap()`, `expect()`,
109+
`panic!`, `todo!`, `dbg!`, and direct `print!`/`eprintln!` in library
110+
code, plus the full pedantic and nursery sets — and CI runs clippy with
111+
`-D warnings`, so every one of them fails the build. Write error
112+
handling with `?` and real error types.
113+
- **pytest treats warnings as errors.** A deprecation warning from a
114+
dependency is a test failure; don't suppress it without a comment.
115+
116+
You can also run the repo's own CI pipeline exactly as CI does — Harmont
117+
dogfoods itself via `.hm/ci.py`:
118+
119+
```sh
120+
hm run ci --backend docker # locally, in Docker
121+
hm cloud login && hm run ci --org <your-org> # or on Harmont Cloud
122+
```
123+
124+
These lines use an installed `hm`; if you only have the freshly built
125+
workspace, substitute `cargo run -p harmont-cli --` for `hm`. The repo's
126+
`.hm/config.toml` pins the maintainer's cloud org, so pass `--org` to
127+
submit cloud runs to your own.
128+
129+
Signing up at [app.harmont.dev](https://app.harmont.dev) gets you cloud runs
130+
of this same pipeline, which is the fastest way to reproduce a CI result.
131+
132+
### Running a single test
133+
134+
```sh
135+
cargo test -p harmont-cli --test cmd_init # one Rust integration test file
136+
cd crates/hm-dsl-engine/harmont-py && uv run pytest tests/test_rust.py -k <name>
137+
```
138+
139+
The Docker-backed integration tests (for example `crates/hm/tests/keep_going.rs`)
140+
are marked `#[ignore]`; run them with a live Docker daemon via
141+
`cargo test -p harmont-cli --test keep_going -- --ignored`.
142+
143+
### Snapshot tests
144+
145+
`hm-pipeline-ir` uses [insta](https://insta.rs) JSON snapshots. If you
146+
change the pipeline IR schema, review and accept the new snapshots with:
147+
148+
```sh
149+
cargo insta review
150+
```
151+
152+
## How the workspace fits together
153+
154+
| Crate | What it is |
155+
|---|---|
156+
| `crates/hm` | The `hm` binary (package `harmont-cli`) — command-line client for the Harmont CI platform. |
157+
| `crates/hm-exec` | Pluggable CI execution backends: local and cloud. |
158+
| `crates/hm-vm` | Local Docker backends that run pipeline steps on your machine. |
159+
| `crates/hm-render` | Build-event renderers (human, with progress bars, and JSON). |
160+
| `crates/hm-dsl-engine` | Evaluates Python pipeline definitions; contains the `harmont` Python package (`harmont-py/`). |
161+
| `crates/hm-pipeline-ir` | The pipeline IR wire-format schema. |
162+
| `crates/hm-config` | Layered configuration and credential storage. |
163+
| `crates/hm-plugin-cloud` | Cloud client library. |
164+
| `crates/hm-plugin-protocol` | Wire types shared between `hm` and plugins. |
165+
| `crates/hm-util` | Shared OS and filesystem utilities. |
166+
167+
A useful mental model: the DSL engine evaluates your `.hm/*.py` pipeline
168+
into IR, an execution backend (local Docker or Harmont Cloud) schedules it
169+
as a DAG, and the binary renders the resulting event stream in your
170+
terminal.
171+
172+
One sync rule to know about: the Python SDK in
173+
`crates/hm-dsl-engine/harmont-py/`, the `hm init` templates in
174+
`crates/hm/src/commands/init_templates/`, and the generated reference docs
175+
on docs.harmont.dev must stay in agreement. If you change a toolchain
176+
helper, update the matching template (roundtrip-tested by
177+
`crates/hm/tests/cmd_init.rs`) and refresh the docstring it is generated
178+
from; a maintainer will regenerate the published docs during review.
179+
180+
## Debugging
181+
182+
Every `hm` command accepts `-v`/`--verbose` for debug-level logging. For
183+
finer control, set `RUST_LOG` with standard tracing filter directives
184+
(for example `RUST_LOG=hm_exec=trace`); when set, it takes precedence over
185+
the flag. To see the raw `BuildEvent` stream that the renderers consume,
186+
run with `hm run --format json`.
187+
188+
When chasing a local-execution bug, the fastest loop is usually a minimal
189+
pipeline in one of the `examples/` projects plus `--verbose`.
190+
For cloud-side behavior, `hm cloud login` followed by
191+
`hm run ci --org <your-org>` against your own
192+
[app.harmont.dev](https://app.harmont.dev) org reproduces what CI sees;
193+
the `--org` flag overrides the org pinned in `.hm/config.toml`.
194+
195+
## Submitting a pull request
196+
197+
- Branch from `main` in your fork.
198+
- Keep the PR scoped to its issue — resist drive-by refactors; file another
199+
issue instead.
200+
- PRs are **squash-merged**, so your PR title becomes the commit that lands.
201+
Write it as a [Conventional Commit](https://www.conventionalcommits.org):
202+
`fix(dsl): reject empty pipeline names`, `feat(render): add JSON event
203+
output`. Use `!` for breaking changes. Individual commits within the PR
204+
can be messy; the title cannot.
205+
- Fill in the PR description with two sections: **Summary** (what and why,
206+
linking the issue) and **Test plan** (what you ran and what you saw).
207+
- Mark the PR as draft while you're still iterating; when review comments
208+
are addressed, re-request review rather than waiting silently.
209+
210+
## Filing issues
211+
212+
For bugs, include:
213+
214+
- `hm --version` output and your OS,
215+
- what you ran, what you expected, and what happened instead,
216+
- the smallest pipeline or command that reproduces it (the `examples/`
217+
projects make good starting points).
218+
219+
For feature requests, describe the problem you're trying to solve before
220+
the solution you have in mind — the discussion usually starts there.
221+
222+
Security issues: please email [marko@harmont.dev](mailto:marko@harmont.dev)
223+
instead of opening a public issue.
224+
225+
## License
226+
227+
Harmont is dual-licensed under [MIT](LICENSE-MIT) and
228+
[Apache 2.0](LICENSE-APACHE). Unless you explicitly state otherwise, any
229+
contribution you intentionally submit for inclusion in the work, as defined
230+
in the Apache-2.0 license, shall be dual-licensed as above, without any
231+
additional terms or conditions. (The `harmont` Python package carries its
232+
own MIT license; contributions to it are MIT-licensed.)
233+
234+
## Code of Conduct
235+
236+
This project follows the
237+
[Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). By
238+
participating, you agree to abide by its terms. Conduct concerns go to
239+
[marko@harmont.dev](mailto:marko@harmont.dev).

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ moving.
362362
- **Discord** — [discord.gg/hm-dev](https://discord.gg/hm-dev)
363363
- **Slack** — [join the workspace](https://join.slack.com/t/harmont-dev/shared_invite/zt-3yt0tiv7r-qHm1O0p0nVh2GU~KKhUk9A)
364364
- **Issues** — [github.com/harmont-dev/harmont-cli/issues](https://github.com/harmont-dev/harmont-cli/issues)
365+
- **Contributing** — see [`CONTRIBUTING.md`](CONTRIBUTING.md) to get started; issues labeled [`good first issue`](https://github.com/harmont-dev/harmont-cli/labels/good%20first%20issue) are a great entry point.
365366

366367
File bugs, request toolchains, or tell us what made you bounce — all of it helps.
367368

0 commit comments

Comments
 (0)