<h1 align="center">
<strong>dev-ci</strong>
<br>
<sup><sub>CI WORKFLOW GENERATOR FOR RUST</sub></sup>
</h1>
<p align="center">
<a href="https://crates.io/crates/dev-ci"><img alt="crates.io" src="https://img.shields.io/crates/v/dev-ci.svg"></a>
<a href="https://crates.io/crates/dev-ci"><img alt="downloads" src="https://img.shields.io/crates/d/dev-ci.svg"></a>
<a href="https://docs.rs/dev-ci"><img alt="docs.rs" src="https://docs.rs/dev-ci/badge.svg"></a>
<a href="https://github.com/jamesgober/dev-ci/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/jamesgober/dev-ci/actions/workflows/ci.yml/badge.svg"></a>
<img alt="MSRV" src="https://img.shields.io/badge/msrv-1.85%2B-blue.svg?style=flat-square" title="Rust Version">
</p>
<p align="center">
CI workflow generator for the <code>dev-*</code> verification suite.
</p>
---
## What it does
`dev-ci` generates calibrated CI workflow files (currently GitHub
Actions; others in the roadmap) from a structured Rust API and a CLI
front-end. One source of truth, byte-deterministic output, every
checkout pinned at `actions/checkout@v5`.
The runtime side — a GitHub Action that runs the entire `dev-*`
verification suite end-to-end inside one job and uploads SARIF —
lands later in the 0.9.x line.
## Quick start (CLI)
```bash
cargo install dev-ci
cd my-rust-project
dev-ci generate \
--with clippy,fmt,docs,msrv \
--msrv 1.85 \
--matrix ubuntu-latest,macos-latest,windows-latest
```
Writes `.github/workflows/ci.yml`. Pass `--print` to send the result
to stdout instead.
## Quick start (Library)
```toml
[dependencies]
dev-ci = "0.9"
```
```rust
use dev_ci::{Generator, Target};
let yaml = Generator::new()
.target(Target::GitHubActions)
.matrix_os(["ubuntu-latest", "macos-latest", "windows-latest"])
.with_clippy()
.with_fmt()
.with_docs()
.with_msrv("1.85")
.generate();
std::fs::write(".github/workflows/ci.yml", yaml).unwrap();
```
## Builder surface
| `target(Target)` | Pick the output platform. Default: `GitHubActions`. |
| `workflow_name(s)` | Set the `name:` field. Default: `"CI"`. |
| `branches(iter)` | Branch filter for both `push` and `pull_request`. Default: `["main"]`. |
| `matrix_os(iter)` | OS list for the `test` matrix. Default: `["ubuntu-latest"]`. |
| `with_cache(bool)` | Toggle `Swatinem/rust-cache@v2`. Default: enabled. |
| `with_workspace()` | Pass `--workspace` to every cargo call. |
| `features(list)` | Pass `--features <list>` to default build/test steps. |
| `with_no_default_features_build()`| Add a `cargo build --no-default-features` step. |
| `with_all_features_build()` | Add `cargo build --all-features` + `cargo test --all-features`. |
| `with_path_dep(PathDep)` | Declare a sibling path-dep to `git clone` before cargo runs. |
| `with_clippy()` | Add a `clippy` job (all-features + no-default-features lint runs). |
| `with_fmt()` | Add a `fmt` job (`cargo fmt --all -- --check`). |
| `with_docs()` | Add a `docs` job with `RUSTDOCFLAGS="-D warnings"`. |
| `with_msrv(version)` | Add an `msrv` job pinning `dtolnay/rust-toolchain@<version>`. |
## Sibling path-deps
For the dev-* suite itself (and any other multi-crate-repo project)
each crate's CI clones its siblings into `..` before running cargo:
```rust
use dev_ci::{Generator, PathDep};
let yaml = Generator::new()
.with_path_dep(PathDep::new("dev-report", "https://github.com/jamesgober/dev-report.git"))
.with_path_dep(PathDep::new("dev-tools", "https://github.com/jamesgober/dev-tools.git"))
.generate();
assert!(yaml.contains("git clone --depth 1 https://github.com/jamesgober/dev-report.git ../dev-report"));
```
The clones land in a single `run: |` step right after
`actions/checkout`, before the toolchain install.
## Determinism
A given `Generator` configuration produces byte-identical YAML across
runs and machines — no clock reads, no random IDs, list iteration is
in insertion order. Two calls to `generate()` on the same `Generator`
return equal strings.
This makes the generated YAML safe to diff during code review and
safe to assert against in unit tests.
## CLI
```text
dev-ci generate [OPTIONS]
```
| `--target github-actions` | `target(Target::GitHubActions)` |
| `--workflow-name <NAME>` | `workflow_name(NAME)` |
| `--branches main,release/*` | `branches([...])` |
| `--matrix ubuntu-latest,macos-latest` | `matrix_os([...])` |
| `--with clippy,fmt,docs,msrv` | `with_clippy()` / `with_fmt()` / `with_docs()` / `with_msrv(...)` |
| `--msrv 1.85` | `with_msrv("1.85")` |
| `--features foo,bar` | `features("foo,bar")` |
| `--no-default-features-build` | `with_no_default_features_build()` |
| `--all-features-build` | `with_all_features_build()` |
| `--workspace` | `with_workspace()` |
| `--no-cache` | `with_cache(false)` |
| `--path-dep name=url` | `with_path_dep(PathDep::new(name, url))` |
| `--output <PATH>` / `--print` | Write to file (default `.github/workflows/ci.yml`) or stdout. |
## Examples
| `examples/basic.rs` | Minimal workflow — single-OS test + clippy + fmt + docs + msrv. |
| `examples/full_suite.rs` | 3-OS matrix, every job, workspace + all-features + no-default builds. |
| `examples/path_deps.rs` | The sibling-clone pattern the dev-* suite itself uses. |
| `examples/write_to_disk.rs` | Generate and write the workflow to a file. |
## The `dev-*` suite
`dev-ci` is part of the wider `dev-*` verification suite:
- [`dev-report`](https://github.com/jamesgober/dev-report) — foundation schema
- [`dev-tools`](https://github.com/jamesgober/dev-tools) — umbrella crate
- [`dev-fixtures`](https://github.com/jamesgober/dev-fixtures) — test environments
- [`dev-bench`](https://github.com/jamesgober/dev-bench) — performance
- [`dev-async`](https://github.com/jamesgober/dev-async) — async validation
- [`dev-stress`](https://github.com/jamesgober/dev-stress) — load testing
- [`dev-chaos`](https://github.com/jamesgober/dev-chaos) — failure injection
- [`dev-coverage`](https://github.com/jamesgober/dev-coverage) — test coverage
- [`dev-security`](https://github.com/jamesgober/dev-security) — vulnerability scanning
- [`dev-deps`](https://github.com/jamesgober/dev-deps) — dependency health
- `dev-fuzz`, `dev-flaky`, `dev-mutate` — landing soon
## Status
`v0.9.x` is the pre-1.0 stabilization line. The generator and CLI are
feature-complete for GitHub Actions output. GitLab CI, Buildkite,
CircleCI targets, and the runtime GitHub Action distribution land in
subsequent 0.9.x releases.
## Minimum supported Rust version
`1.85` — pinned in `Cargo.toml` via `rust-version` and verified by
the MSRV job in CI.
## License
Apache-2.0. See [LICENSE](LICENSE).