Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ jobs:
with:
shared-key: examples-hm

- name: Install esbuild (for harmont-ts bundle)
working-directory: crates/hm-dsl-engine/harmont-ts
run: npm ci

- name: Build hm
run: cargo build -p harmont-cli

Expand Down
60 changes: 0 additions & 60 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2

- name: Install esbuild (for harmont-ts bundle)
working-directory: crates/hm-dsl-engine/harmont-ts
run: npm ci

- name: Set version from tag
run: |
VERSION="${GITHUB_REF_NAME#v}"
Expand Down Expand Up @@ -181,52 +177,6 @@ jobs:
cargo publish -p harmont-cli --token ${{ secrets.CRATES_IO_TOKEN }} --allow-dirty --no-verify
fi

npm:
name: Publish to npm
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"
cache: npm
cache-dependency-path: crates/hm-dsl-engine/harmont-ts/package-lock.json

# node 20 ships npm 10, which can sign provenance but cannot AUTHENTICATE
# via OIDC trusted publishing — that needs npm >= 11.5.1. Without it the
# publish PUT goes out unauthenticated and npm masks it as a 404. Upgrade
# so the configured trusted publisher actually authenticates the publish.
- name: Upgrade npm for OIDC trusted publishing
run: npm install -g npm@latest

- name: Install dependencies
working-directory: crates/hm-dsl-engine/harmont-ts
run: npm ci

- name: Build
working-directory: crates/hm-dsl-engine/harmont-ts
run: npm run build

- name: Set version from tag
working-directory: crates/hm-dsl-engine/harmont-ts
run: npm version "${GITHUB_REF_NAME#v}" --no-git-tag-version

- name: Publish
working-directory: crates/hm-dsl-engine/harmont-ts
run: |
VERSION="${GITHUB_REF_NAME#v}"
if npm view @harmont/hm@"$VERSION" version 2>/dev/null; then
echo "@harmont/hm@$VERSION already published, skipping"
else
npm publish --access public --provenance
fi

pypi:
name: Publish to PyPI
runs-on: ubuntu-latest
Expand Down Expand Up @@ -303,16 +253,6 @@ jobs:
if: matrix.musl
run: sudo apt-get update && sudo apt-get install -y musl-tools

- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: crates/hm-dsl-engine/harmont-ts/package-lock.json

- name: Install esbuild
working-directory: crates/hm-dsl-engine/harmont-ts
run: npm ci

- name: Set version from tag
run: |
VERSION="${GITHUB_REF_NAME#v}"
Expand Down
21 changes: 2 additions & 19 deletions .hm/ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ def rust_project(shared_base: hm.Target[hm.Step]) -> tuple[hm.Step, ...]:
# the build emits an 18-byte stub and the bundled_sources tests fail (CLI-37).
# Installing Node here also lets the JS-runtime-gated render tests actually
# run instead of self-skipping.
ts_deps = hm.js.project(
path="crates/hm-dsl-engine/harmont-ts",
base=shared_base,
).install()
project = hm.rust.project(path=".", base=ts_deps)
project = hm.rust.project(path=".")
return hm.group([
project.test(), # cargo test --workspace --locked — every package
project.clippy(),
Expand All @@ -51,18 +47,6 @@ def py_project(shared_base: hm.Target[hm.Step]) -> tuple[hm.Step, ...]:
])


@hm.target()
def ts_project(shared_base: hm.Target[hm.Step]) -> tuple[hm.Step, ...]:
project = hm.js.project(
path="crates/hm-dsl-engine/harmont-ts",
base=shared_base,
)
return hm.group([
project.run("typecheck", label=":typescript: tsc"),
project.run("test", label=":test_tube: vitest"),
])


@hm.pipeline(
"ci",
env={"CI": "true"},
Expand All @@ -74,6 +58,5 @@ def ts_project(shared_base: hm.Target[hm.Step]) -> tuple[hm.Step, ...]:
def ci(
rust_project: hm.Target[tuple[hm.Step, ...]],
py_project: hm.Target[tuple[hm.Step, ...]],
ts_project: hm.Target[tuple[hm.Step, ...]],
) -> list:
return [rust_project, py_project, ts_project]
return [rust_project, py_project]
12 changes: 4 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,18 @@ The `cli/` directory is a Cargo workspace.
- `crates/hm-util/` — shared OS and filesystem utilities.
- `crates/hm-plugin-protocol/` — wire types (serde structs only).
- `crates/hm-plugin-sdk/` — authoring SDK for plugin writers.
Run `cargo build` from the workspace root. Build requires esbuild
(`npm ci` in `crates/hm-dsl-engine/harmont-ts/`).
Run `cargo build` from the workspace root.

For cross-cutting doctrine see [PRINCIPLES.md](../PRINCIPLES.md).

## DSLs
## DSL

Both DSLs live inside `crates/hm-dsl-engine/` so they ship with the crate:

- `crates/hm-dsl-engine/harmont-py/` — the `harmont` Python package (pipeline DSL).
- `crates/hm-dsl-engine/harmont-ts/` — the `harmont` TypeScript package (pipeline DSL).
The `harmont` Python package (pipeline DSL) lives inside `crates/hm-dsl-engine/harmont-py/` so it ships with the crate.

## Keep the SDK, `hm init` templates, and docs in sync

The toolchain helpers in `crates/hm-dsl-engine/` (e.g.
`harmont-py/harmont/_rust.py`, `harmont-ts/src/toolchains/rust.ts`) are the
`harmont-py/harmont/_rust.py`) are the
**public authoring SDK**. They have two downstream surfaces that drift silently
unless you update them in the same change. **A toolchain change is not done until
all three agree:**
Expand Down
44 changes: 5 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
</p>

<p>
<b>CI/CD as real code. Write your pipelines in Python or TypeScript, then run the exact same pipeline locally in Docker or on managed runners in <a href="https://app.harmont.dev">Harmont Cloud</a> — with layer caching and DAG parallelism built in.</b>
<b>CI/CD as real code. Write your pipelines in Python, then run the exact same pipeline locally in Docker or on managed runners in <a href="https://app.harmont.dev">Harmont Cloud</a> — with layer caching and DAG parallelism built in.</b>
</p>

## What is Harmont?

Harmont lets you define CI/CD pipelines in **TypeScript or Python** and run them
Harmont lets you define CI/CD pipelines in **Python** and run them
two ways from a single definition: instantly on your own machine in Docker, or on
managed runners in [Harmont Cloud](https://app.harmont.dev). It's the same
pipeline either way — the run you debug locally is byte-for-byte the run that
Expand Down Expand Up @@ -76,7 +76,7 @@ cargo install harmont-cli
hm init
```

`hm init` scaffolds a working `.hm/pipeline.{py,ts}` from a template and offers
`hm init` scaffolds a working `.hm/pipeline.{py}` from a template and offers
to install Claude Code skills that write and maintain your pipeline. Run it and
pick your stack from the menu, or name a template up front with `-t`:

Expand All @@ -99,10 +99,7 @@ same pipeline, on managed runners. See [Cloud](#cloud) below.

### Or write it by hand

A pipeline is just code. Save this as `.hm/pipeline.py` (or `.hm/pipeline.ts`):

<details open>
<summary><b>Python</b></summary>
A pipeline is just code. Save this as `.hm/pipeline.py`:

```python
import harmont as hm
Expand All @@ -125,37 +122,6 @@ def ci(project: hm.Target[PythonToolchain]) -> tuple[hm.Step, ...]:
)
```

</details>

<details>
<summary><b>TypeScript</b></summary>

```typescript
import { pipeline, push, type PipelineDefinition } from "@harmont/hm";
import { python } from "@harmont/hm/toolchains";

const project = python({ path: "." });

const pipelines: PipelineDefinition[] = [
{
slug: "ci",
triggers: [push({ branch: "main" })],
pipeline: pipeline(
[
project.test(),
project.lint(),
project.fmt(),
project.typecheck(),
],
),
},
];

export default pipelines;
```

</details>

```sh
hm run ci
```
Expand Down Expand Up @@ -372,7 +338,7 @@ input reference, sub-actions, and caching details.
## Examples

The [`examples/`](./examples) directory has a complete, runnable pipeline for
each stack — every one shipped in **both** Python and TypeScript:
each stack:

| | | |
|---|---|---|
Expand Down
2 changes: 1 addition & 1 deletion crates/hm-dsl-engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.0.0-dev"
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "DSL engine: evaluate Python/TypeScript pipeline definitions via system runtimes."
description = "DSL engine: evaluate Python pipeline definitions via system runtimes."
keywords = ["ci", "harmont", "dsl"]
categories = ["command-line-utilities"]

Expand Down
68 changes: 0 additions & 68 deletions crates/hm-dsl-engine/build.rs

This file was deleted.

28 changes: 0 additions & 28 deletions crates/hm-dsl-engine/harmont-ts/CLAUDE.md

This file was deleted.

Loading
Loading