ci: add GitHub Actions workflow (fmt + clippy + test + doc)#31
Merged
Conversation
…p debt
ferrolearn had no PR CI before this — only Dependabot at the org level.
This adds a strict, parallel-jobs GitHub Actions workflow plus the fmt
+ clippy cleanup needed to land it green from day one.
## New workflow (.github/workflows/ci.yml)
Four parallel jobs on every push to main + every PR targeting main:
- `cargo fmt --check` — strict rustfmt parity with main
- `cargo clippy -D warnings` — strict lints across `--workspace --all-targets`
- `cargo test --release` — full workspace test suite in release
- `cargo doc --no-deps` — docs build (no `-D warnings` yet; see below)
Architectural choices:
- **Independent jobs**: fmt / clippy / test / doc all run in parallel so
one failure doesn't gate the others — contributors see the full picture
in a single CI run.
- **Concurrency control**: `cancel-in-progress` on the same ref so a
fix-up push kills the stale run.
- **Permissions hardening**: `contents: read` only — workflow doesn't
push, comment, or deploy.
- **Caching**: `Swatinem/rust-cache@v2` keyed per-job so each artifact
pool stays isolated (clippy vs test vs doc).
- **Stable only**: no MSRV matrix yet — workspace declares `rust-version
= "1.85"` but enforcement can come as a separate matrix job if MSRV
regressions become a practical concern.
- **Doc job is advisory**: `RUSTDOCFLAGS=-D warnings` would be ideal but
the workspace currently has multiple broken intra-doc links
(`FerroError::*` variants in `ferrolearn-io`, etc.). Job catches
syntax-level doc errors that would break the docs.rs build; lint
tightening tracked as follow-up.
## Pre-CI cleanup so it lands green
- **`cargo fmt` applied across the workspace** (66 files, ~1500 line
diff, all whitespace). Pure mechanical churn; brings the tree to a
rustfmt-clean baseline so future drift gets caught immediately.
- **9 clippy violations fixed** to clear `-D warnings`:
- 8× `clippy::needless_range_loop` (6 files: `categorical.rs`,
`gmm.rs`, `lda.rs`, `gradient_boosting.rs`, `hist_gradient_boosting.rs`,
`cluster/tests/conformance_sklearn.rs`). Each fixed with a
scoped `#[allow(clippy::needless_range_loop)]` on the enclosing
function — these are math-style matrix index loops (per-class score
rows, smoothing, k-means++ candidate search) where range-by-index
is the natural form; rewriting to `.iter().enumerate()` would
obscure the intent. The allow is explicit and per-function so
new loops in adjacent code still get linted.
- 1× `clippy::approximate_constant` — false positive in
`ferrolearn-neural/src/mlp.rs` test: `3.14` was a placeholder for
the Identity activation passthrough test, not an approximation of
π. Changed to `1.25` with a comment.
- 1× `clippy::unused_imports` — `Transform` not used in
`ferrolearn-neural/tests/conformance_wave4.rs`.
- **Auto-fixed by `cargo clippy --fix`**: several `clippy::redundant_closure`
/ `clippy::derefed_type_is_same_as_origin` / `clippy::manual_range_patterns`
/ `clippy::length_comparison_to_one` issues across
`ferrolearn-preprocess`, `ferrolearn-tree`, `ferrolearn-linear`,
`ferrolearn-numerical`, `ferrolearn-model-sel`. ~10 files touched.
## Verification
```
cargo fmt --check # clean
cargo clippy --workspace --all-targets -- -D warnings # clean
cargo test --workspace --release --no-run # builds
cargo doc --workspace --no-deps --document-private-items # builds (1 warning)
```
## Known follow-ups (out of scope here)
1. Doc-link cleanup: ~10 broken intra-doc links in `ferrolearn-io` +
`ferrolearn-bayes` that prevent tightening to `RUSTDOCFLAGS=-D warnings`.
2. MSRV enforcement: add a `cargo +1.85 check` matrix job if MSRV
regressions show up.
3. Coverage / dependabot review: not added; can come later.
Refs forecast-bio/decode#3 (upstream contributions backlog).
5b2da1f to
474a95e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ferrolearn had no PR CI before this — only Dependabot at the org level. This PR adds a strict, parallel-jobs GitHub Actions workflow + the fmt/clippy cleanup needed to land it green from day one.
New workflow (
.github/workflows/ci.yml)Four parallel jobs on every push to
main+ every PR targetingmain:cargo fmt --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspace --release --lib --testscargo doc --workspace --no-deps --document-private-itemsArchitectural choices:
cancel-in-progresson the same ref so a fix-up push kills the stale run.contents: readonly. Workflow doesn't push, comment, or deploy.Swatinem/rust-cache@v2keyed per-job so each artifact pool stays isolated.rust-version = "1.85"but enforcement can come as a separate matrix job if MSRV regressions become a practical concern.Pre-CI cleanup so it lands green
cargo fmtapplied across the workspaceclippy::needless_range_loopfixed with scoped#[allow]categorical.rs,gmm.rs,lda.rs,gradient_boosting.rs,hist_gradient_boosting.rs,cluster/tests/conformance_sklearn.rs.clippy::approximate_constant(false positive)3.14inmlp.rs::test_activate_identitywas a placeholder for an Identity-activation passthrough check, not π. Changed to1.25with a comment.clippy::unused_importsTransformnot used inferrolearn-neural/tests/conformance_wave4.rs.cargo clippy --fixauto-appliedferrolearn-preprocess,ferrolearn-tree,ferrolearn-linear,ferrolearn-numerical,ferrolearn-model-sel—clippy::redundant_closure,clippy::derefed_type_is_same_as_origin,clippy::manual_range_patterns,clippy::length_comparison_to_one.Verification
Known follow-ups (out of scope)
ferrolearn-io+ferrolearn-bayes(FerroError::Variantpaths that don't resolve). Tighten the doc job toRUSTDOCFLAGS=-D warningsonce those land.cargo +1.85 checkmatrix job if MSRV regressions become a practical concern.Diff shape
Total: 79 files changed (+1605 / −791), most of it the mechanical fmt churn.
🤖 Generated with Claude Code