lme-python 0.1.11__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lme_python-0.2.2/.github/dependabot.yml +10 -0
- lme_python-0.2.2/.github/workflows/audit.yml +62 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/.github/workflows/benchmarks.yml +21 -12
- lme_python-0.2.2/.github/workflows/cache-prime.yml +121 -0
- lme_python-0.2.2/.github/workflows/ci.yml +267 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/.github/workflows/crate-publish-dry-run.yml +14 -9
- {lme_python-0.1.11 → lme_python-0.2.2}/.github/workflows/fuzz-smoke.yml +17 -6
- lme_python-0.2.2/.github/workflows/python-release.yml +262 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/.github/workflows/repo-metadata.yml +1 -1
- lme_python-0.2.2/AGENTS.md +112 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/BENCHMARKS.md +50 -23
- {lme_python-0.1.11 → lme_python-0.2.2}/BENCHMARK_COVERAGE.md +38 -22
- {lme_python-0.1.11 → lme_python-0.2.2}/CHANGELOG.md +68 -4
- lme_python-0.2.2/CI_PERFORMANCE.md +63 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/CONTRIBUTING.md +21 -13
- {lme_python-0.1.11 → lme_python-0.2.2}/Cargo.lock +9 -171
- {lme_python-0.1.11 → lme_python-0.2.2}/Cargo.toml +15 -3
- {lme_python-0.1.11 → lme_python-0.2.2}/GUIDE.md +145 -23
- {lme_python-0.1.11 → lme_python-0.2.2}/OPTIMIZATION.md +107 -20
- lme_python-0.2.2/PKG-INFO +67 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/README.md +16 -14
- {lme_python-0.1.11 → lme_python-0.2.2}/RELEASING.md +51 -20
- lme_python-0.2.2/REPO_COMPLETION_BY_AREA.md +110 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/Taskfile.yml +33 -3
- {lme_python-0.1.11 → lme_python-0.2.2}/USABILITY.md +20 -18
- {lme_python-0.1.11 → lme_python-0.2.2}/benches/bench_math.rs +51 -0
- lme_python-0.2.2/benchmarks/external-nlmm-inference-python-timings-2026-08-14.json +198 -0
- lme_python-0.2.2/benchmarks/fair-rust-julia-reference-2026-07-16-cold-fit-lt1.json +363 -0
- lme_python-0.2.2/benchmarks/fair-rust-julia-reference-2026-07-22-full-tier-a.json +1593 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/COMPARISONS.md +24 -5
- lme_python-0.2.2/comparisons/bench_external_timings.R +138 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/bench_fair_julia_timing.jl +2 -1
- lme_python-0.2.2/comparisons/pastes_emmeans.R +48 -0
- lme_python-0.2.2/comparisons/pastes_glht.R +36 -0
- lme_python-0.2.2/comparisons/sleepstudy_confint_profile.R +16 -0
- lme_python-0.2.2/completion_manifest.json +20 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/docs/CALO_CALIBRATION.md +2 -2
- lme_python-0.2.2/examples/bench_external_timings.rs +262 -0
- lme_python-0.2.2/examples/dump_cascade_fixtures.rs +339 -0
- lme_python-0.2.2/examples/explore_formula_ast.rs +137 -0
- lme_python-0.2.2/examples/explore_mcp_adjust.rs +78 -0
- lme_python-0.2.2/examples/explore_theta_grid.rs +76 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/legal/fixture-provenance.json +6 -1
- {lme_python-0.1.11 → lme_python-0.2.2}/pyproject.toml +8 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/Cargo.lock +10 -172
- {lme_python-0.1.11 → lme_python-0.2.2}/python/Cargo.toml +2 -1
- {lme_python-0.1.11 → lme_python-0.2.2}/python/PYTHON_GUIDE.md +115 -24
- lme_python-0.2.2/python/README.md +44 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/verification_project/parity.py +5 -3
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/verification_project/run.py +1 -1
- {lme_python-0.1.11 → lme_python-0.2.2}/python/lme_python.pyi +126 -3
- {lme_python-0.1.11 → lme_python-0.2.2}/python/src/lib.rs +919 -207
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_api_parity.py +59 -9
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_cv.py +20 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_nlmer_custom_mean.py +25 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/README.md +7 -3
- lme_python-0.2.2/scripts/ci/check_completion_score.py +101 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/lme_ci.py +447 -33
- lme_python-0.2.2/scripts/explorations/README.md +20 -0
- lme_python-0.2.2/scripts/run_external_timings.py +236 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/run_fair_rust_julia_benchmark.py +2 -2
- lme_python-0.2.2/src/basis.rs +529 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/bootstrap.rs +294 -18
- {lme_python-0.1.11 → lme_python-0.2.2}/src/contrast.rs +16 -12
- {lme_python-0.1.11 → lme_python-0.2.2}/src/cv.rs +309 -2
- lme_python-0.2.2/src/emmeans.rs +459 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/family.rs +65 -0
- lme_python-0.2.2/src/formula.rs +1360 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/glmm_math.rs +154 -47
- {lme_python-0.1.11 → lme_python-0.2.2}/src/intercept_blocked.rs +43 -3
- {lme_python-0.1.11 → lme_python-0.2.2}/src/kenward_roger.rs +48 -20
- {lme_python-0.1.11 → lme_python-0.2.2}/src/lib.rs +317 -106
- {lme_python-0.1.11 → lme_python-0.2.2}/src/math.rs +90 -34
- lme_python-0.2.2/src/mcp.rs +350 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/model_matrix.rs +784 -295
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/fit.rs +269 -7
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/formula.rs +46 -3
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/mean.rs +10 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/mean_fn.rs +26 -1
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/mod.rs +15 -1
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/self_start.rs +100 -0
- lme_python-0.2.2/src/nlmm/ssasympoff.rs +46 -0
- lme_python-0.2.2/src/nlmm/ssasymporig.rs +43 -0
- lme_python-0.2.2/src/nlmm/ssbiexp.rs +49 -0
- lme_python-0.2.2/src/nlmm/ssfpl.rs +50 -0
- lme_python-0.2.2/src/nlmm/ssweibull.rs +53 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/optimizer.rs +221 -13
- {lme_python-0.1.11 → lme_python-0.2.2}/src/perf_diag.rs +2 -1
- lme_python-0.2.2/src/profile_ci.rs +1118 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/robust.rs +3 -2
- {lme_python-0.1.11 → lme_python-0.2.2}/src/satterthwaite.rs +2 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/simulate.rs +49 -9
- lme_python-0.2.2/src/studentized_range.rs +224 -0
- lme_python-0.2.2/tests/ci_consolidated.rs +112 -0
- lme_python-0.2.2/tests/data/dyestuff_intercept_reml.json +17 -0
- lme_python-0.2.2/tests/data/glmm_binomial_agq.json +9 -0
- lme_python-0.2.2/tests/data/glmm_binomial_cloglog.json +19 -0
- lme_python-0.2.2/tests/data/glmm_gamma_dyestuff.json +18 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/golden_parity_manifest.json +277 -0
- lme_python-0.2.2/tests/data/pastes_emmeans.json +15 -0
- lme_python-0.2.2/tests/data/pastes_glht_tukey.json +18 -0
- lme_python-0.2.2/tests/data/r_edge_case_matrix.json +432 -0
- lme_python-0.2.2/tests/data/sleepstudy_confint_profile.json +11 -0
- lme_python-0.2.2/tests/data/sleepstudy_confint_profile_vc.json +12 -0
- lme_python-0.2.2/tests/data/ssasympoff_nlmer.json +10 -0
- lme_python-0.2.2/tests/data/ssasympoff_synthetic.csv +61 -0
- lme_python-0.2.2/tests/data/ssasymporig_nlmer.json +10 -0
- lme_python-0.2.2/tests/data/ssasymporig_synthetic.csv +61 -0
- lme_python-0.2.2/tests/data/ssbiexp_nlmer.json +10 -0
- lme_python-0.2.2/tests/data/ssbiexp_synthetic.csv +97 -0
- lme_python-0.2.2/tests/data/ssfpl_nlmer.json +10 -0
- lme_python-0.2.2/tests/data/ssfpl_synthetic.csv +61 -0
- lme_python-0.2.2/tests/data/ssweibull_nlmer.json +10 -0
- lme_python-0.2.2/tests/data/ssweibull_synthetic.csv +109 -0
- lme_python-0.2.2/tests/generate_nlmm_fixtures.R +354 -0
- lme_python-0.2.2/tests/generate_r_edge_case_matrix.R +211 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_anova.rs +2 -0
- lme_python-0.2.2/tests/test_bootstrap.rs +331 -0
- lme_python-0.2.2/tests/test_confint_profile.rs +198 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_coverage_gaps.rs +2 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_cv.rs +59 -0
- lme_python-0.2.2/tests/test_emmeans.rs +166 -0
- lme_python-0.2.2/tests/test_explorations.rs +159 -0
- lme_python-0.2.2/tests/test_external_timings_artifact.rs +72 -0
- lme_python-0.2.2/tests/test_formula.rs +94 -0
- lme_python-0.2.2/tests/test_formula_stress.rs +635 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_glmm.rs +96 -4
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_glmm_offset_grouseticks.rs +11 -1
- lme_python-0.2.2/tests/test_mcp.rs +182 -0
- lme_python-0.2.2/tests/test_nlmm_agq.rs +75 -0
- lme_python-0.2.2/tests/test_nlmm_bounds.rs +153 -0
- lme_python-0.2.2/tests/test_nlmm_ss_new_means.rs +132 -0
- lme_python-0.2.2/tests/test_nlmm_ssasymp_off_orig.rs +76 -0
- lme_python-0.2.2/tests/test_r_edge_case_matrix.rs +247 -0
- lme_python-0.1.11/.github/workflows/audit.yml +0 -57
- lme_python-0.1.11/.github/workflows/ci.yml +0 -228
- lme_python-0.1.11/.github/workflows/python-release.yml +0 -169
- lme_python-0.1.11/AGENTS.md +0 -195
- lme_python-0.1.11/PKG-INFO +0 -15
- lme_python-0.1.11/REPO_COMPLETION_BY_AREA.md +0 -102
- lme_python-0.1.11/scripts/ast_explorations/test_fiasto.rs +0 -6
- lme_python-0.1.11/scripts/ast_explorations/test_fiasto_offset.rs +0 -6
- lme_python-0.1.11/src/formula.rs +0 -372
- lme_python-0.1.11/tests/generate_nlmm_fixtures.R +0 -124
- lme_python-0.1.11/tests/test_bootstrap.rs +0 -131
- lme_python-0.1.11/tests/test_formula.rs +0 -11
- lme_python-0.1.11/tests/test_formula_stress.rs +0 -316
- lme_python-0.1.11/tests/test_nlmm_agq.rs +0 -37
- {lme_python-0.1.11 → lme_python-0.2.2}/.JuliaFormatter.toml +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/.gitignore +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/LICENSE +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/LICENSES/Apache-2.0.txt +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/LICENSES/BSD-3-Clause-OpenBLAS.txt +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/LICENSES/GPL-2.0-or-later.txt +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/LICENSES/Intel-Simplified-Software-License.txt +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/LICENSES/LGPL-2.1-only.txt +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/RELINKING.md +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/THIRD_PARTY_NOTICES.md +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benches/bench_load_production.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-04.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-06.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-08.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-direct-intercept-gram.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-full-lmm.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-glmm.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-large-intercept-setup.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-large-slopes-linear-cache.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-large-slopes.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09-sleepstudy-slopes.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-09.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/benchmarks/fair-rust-julia-reference-2026-07-10-cold-setup-followup.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/bench_fair_julia_perf.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/bench_fair_rust_julia.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/bench_perf_breakdown.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/categorical_anova.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/categorical_anova.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/categorical_anova.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/categorical_anova.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/comparison_chart.png +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_cbpp.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_cbpp.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_cbpp.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_cbpp.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_gaussian.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_gaussian.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_gaussian.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_gaussian.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_grouseticks.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_grouseticks.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_grouseticks.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/glmm_grouseticks.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmer_weighted.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmer_weighted.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmer_weighted.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmer_weighted.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_dyestuff.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_dyestuff.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_dyestuff.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_dyestuff.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_pastes.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_pastes.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_pastes.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_pastes.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_penicillin.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_penicillin.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_penicillin.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/lmm_penicillin.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/nlmm_sspower.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/glmm_offset.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/glmm_offset.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/glmm_probit.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/glmm_probit.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/glmm_weighted.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/glmm_weighted.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/parity_r_setup.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/sleepstudy_offset.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity/sleepstudy_offset.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/parity_export.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/r_setup.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy_ml.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy_ml.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy_ml.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/comparisons/sleepstudy_ml.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/docs/benchmarks/app.js +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/docs/benchmarks/index.html +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/docs/benchmarks/styles.css +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/docs/index.html +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/examples/batch_sspower_cpu.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/examples/nlmm_fixture_dump.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/lefthook.yml +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/legal/dependency-license-exceptions.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/mise.toml +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/glmer_cbpp.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/glmer_grouseticks.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/lm_basics.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/lmer_sleepstudy.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/model_comparison.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/.gitignore +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/README.md +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/compare_plots.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/figure_specs.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/find_rscript.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/numeric_overlay.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/paths.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/plot_demo.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/plot_r.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/plotting_demo/run_all.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/verification_project/README.md +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/verification_project/conftest.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/verification_project/paths.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/examples/verification_project/test_parity.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_basic.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_dataframe_inputs.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_golden_parity.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_simulate_scale.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/tests/test_wheel_notices.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/python/uv.lock +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/build_benchmark_site.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/check_legal_compliance.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/julia_format.jl +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/package_wheel_notices.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/r_format.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/ci/run.sh +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/dump_dyestuff.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/dump_pastes.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/local_ci.ps1 +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/local_ci.sh +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/make_penicillin_csv.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/plot_comparisons.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/run_cross_language_benchmarks.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/run_perf_breakdown.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/sync_github_repo_metadata.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/scripts/verify_cross_language_parity.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/anova.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/anova_contrasts.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/ddf.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/kr_modcomp.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/kr_vcov_adj.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/predict.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/re_cov.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/ssasymp.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/ssgompertz.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/sslogis.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/ssmicmen.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/nlmm/sspower.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/src/quadrature.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/categorical_anova_test.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/cbpp_binary.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/cbpp_binary_weighted.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/dyestuff.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/glmm_binomial.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/glmm_binomial_probit.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/glmm_binomial_weighted.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/glmm_poisson.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/glmm_poisson_offset.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/grouseticks.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/intercept_only.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/mock_crossed.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/mock_ml.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/orange.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/orange_nlmer.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/pastes.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/pastes_cask_reml.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/penicillin.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/penicillin.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/random_slopes.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/sleepstudy.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/sleepstudy_offset_reml.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/ssasymp_synthetic.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/ssfol_nlmer.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/ssgompertz_nlmer.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/ssgompertz_synthetic.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/ssmicmen_nlmer.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/ssmicmen_synthetic.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/sspower_nlmer.json +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/data/sspower_synthetic.csv +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/gen_nlmm_extras.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/generate_mock_data.py +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/generate_test_data.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_anova_types.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_conditional_real.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_confint_simulate.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_contrast.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_coverage_edge_cases.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_crossed_mock.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_e2e_lmer.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_edge_cases.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_errors.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_failure_modes.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_gaps.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_glmm_links.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_glmm_weighted.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_golden_parity.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_intercept_only.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_kenward_roger.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_kr_modcomp_pastes.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_ml_optimization.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_custom_mean.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_orange.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_orange_multi_re.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_self_start.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_ssasymp.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_ssfol.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_ssmicmen.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_nlmm_sspower.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_no_intercept.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_numerical_parity.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_predict.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_production_load.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_random_slopes.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_robust.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_sandwich_math.R +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_satterthwaite.rs +0 -0
- {lme_python-0.1.11 → lme_python-0.2.2}/tests/test_statistical_identities.rs +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: Security audit
|
|
2
|
+
|
|
3
|
+
# Release CI calls this workflow as a required publication gate.
|
|
4
|
+
# A weekly schedule and workflow_dispatch provide continuous/on-demand audits.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
workflow_call:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: "17 4 * * 1"
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: audit-${{ github.workflow }}-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
audit:
|
|
21
|
+
name: cargo audit
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
25
|
+
|
|
26
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
27
|
+
with:
|
|
28
|
+
toolchain: stable
|
|
29
|
+
|
|
30
|
+
- name: Install cargo-audit
|
|
31
|
+
uses: taiki-e/install-action@7f4eb899022d8fe70b20c4f3de697aa85c309026 # v2
|
|
32
|
+
with:
|
|
33
|
+
tool: cargo-audit@0.22.1
|
|
34
|
+
|
|
35
|
+
- name: Run cargo audit (root)
|
|
36
|
+
# paste is required by argmin 0.11; RUSTSEC-2024-0436 is informational
|
|
37
|
+
# and has no patched argmin release. Deny every other warning.
|
|
38
|
+
run: cargo audit --deny warnings --ignore RUSTSEC-2024-0436
|
|
39
|
+
|
|
40
|
+
- name: Run cargo audit (python/)
|
|
41
|
+
working-directory: python
|
|
42
|
+
run: cargo audit --deny warnings --ignore RUSTSEC-2024-0436
|
|
43
|
+
|
|
44
|
+
pip-audit:
|
|
45
|
+
name: pip-audit (uv.lock)
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
49
|
+
|
|
50
|
+
- name: Set up uv
|
|
51
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
52
|
+
with:
|
|
53
|
+
python-version: "3.11"
|
|
54
|
+
enable-cache: true
|
|
55
|
+
cache-dependency-glob: "python/uv.lock"
|
|
56
|
+
|
|
57
|
+
- name: pip-audit
|
|
58
|
+
working-directory: python
|
|
59
|
+
run: |
|
|
60
|
+
set -euo pipefail
|
|
61
|
+
uv sync --extra dev --no-install-project
|
|
62
|
+
uv run --no-sync pip-audit
|
|
@@ -29,15 +29,17 @@ jobs:
|
|
|
29
29
|
name: Criterion Benchmarks
|
|
30
30
|
runs-on: ubuntu-latest
|
|
31
31
|
steps:
|
|
32
|
-
- uses: actions/checkout@
|
|
32
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
33
33
|
|
|
34
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
34
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
35
|
+
with:
|
|
36
|
+
toolchain: stable
|
|
35
37
|
|
|
36
38
|
- name: Install OpenBLAS
|
|
37
39
|
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
38
40
|
|
|
39
41
|
- name: Cache cargo registry and build outputs
|
|
40
|
-
uses: actions/cache@
|
|
42
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
41
43
|
with:
|
|
42
44
|
path: |
|
|
43
45
|
~/.cargo/registry
|
|
@@ -55,7 +57,7 @@ jobs:
|
|
|
55
57
|
tar -czf "benchmark-results/criterion-${{ github.sha }}.tar.gz" target/criterion
|
|
56
58
|
|
|
57
59
|
- name: Upload Criterion artifact
|
|
58
|
-
uses: actions/upload-artifact@v7
|
|
60
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
59
61
|
with:
|
|
60
62
|
name: criterion-${{ github.sha }}
|
|
61
63
|
path: benchmark-results/criterion-${{ github.sha }}.tar.gz
|
|
@@ -82,11 +84,13 @@ jobs:
|
|
|
82
84
|
BENCH_REPEATS: ${{ github.event_name == 'workflow_dispatch' && inputs.repeats || '3' }}
|
|
83
85
|
R_LIBS_USER: ${{ github.workspace }}/.r-lib
|
|
84
86
|
steps:
|
|
85
|
-
- uses: actions/checkout@
|
|
87
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
86
88
|
|
|
87
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
89
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
90
|
+
with:
|
|
91
|
+
toolchain: stable
|
|
88
92
|
|
|
89
|
-
- uses: actions/setup-python@
|
|
93
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
90
94
|
with:
|
|
91
95
|
python-version: "3.11"
|
|
92
96
|
|
|
@@ -101,7 +105,7 @@ jobs:
|
|
|
101
105
|
julia --version
|
|
102
106
|
|
|
103
107
|
- name: Cache cargo registry and build outputs
|
|
104
|
-
uses: actions/cache@
|
|
108
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
105
109
|
with:
|
|
106
110
|
path: |
|
|
107
111
|
~/.cargo/registry
|
|
@@ -157,9 +161,10 @@ jobs:
|
|
|
157
161
|
|
|
158
162
|
- name: Upload cross-language artifact
|
|
159
163
|
if: always()
|
|
160
|
-
uses: actions/upload-artifact@v7
|
|
164
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
161
165
|
with:
|
|
162
166
|
name: cross-language-${{ github.sha }}
|
|
167
|
+
if-no-files-found: ignore
|
|
163
168
|
path: |
|
|
164
169
|
benchmark-results/cross-language-${{ github.sha }}.json
|
|
165
170
|
benchmark-results/fair-rust-julia-${{ github.sha }}.json
|
|
@@ -176,9 +181,13 @@ jobs:
|
|
|
176
181
|
gh release create "${GITHUB_REF_NAME}" --title "${GITHUB_REF_NAME}"
|
|
177
182
|
fi
|
|
178
183
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
184
|
+
cross_json="benchmark-results/cross-language-${{ github.sha }}.json"
|
|
185
|
+
fair_json="benchmark-results/fair-rust-julia-${{ github.sha }}.json"
|
|
186
|
+
if [ -f "$cross_json" ]; then
|
|
187
|
+
gh release upload "${GITHUB_REF_NAME}" "$cross_json" --clobber
|
|
188
|
+
fi
|
|
189
|
+
if [ -f "$fair_json" ]; then
|
|
190
|
+
gh release upload "${GITHUB_REF_NAME}" "$fair_json" --clobber
|
|
182
191
|
fi
|
|
183
192
|
|
|
184
193
|
- name: Fail if cross-language benchmarks failed
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
name: Prime Rust caches
|
|
2
|
+
|
|
3
|
+
# PR caches are scoped to a single pull request. Keep trusted default-branch
|
|
4
|
+
# dependency caches warm so new PRs do not start by rebuilding Polars and BLAS.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- master
|
|
10
|
+
paths:
|
|
11
|
+
- "Cargo.toml"
|
|
12
|
+
- "Cargo.lock"
|
|
13
|
+
- "python/Cargo.toml"
|
|
14
|
+
- "python/Cargo.lock"
|
|
15
|
+
- "rust-toolchain"
|
|
16
|
+
- "rust-toolchain.toml"
|
|
17
|
+
- ".cargo/**"
|
|
18
|
+
- ".github/workflows/ci.yml"
|
|
19
|
+
- ".github/workflows/cache-prime.yml"
|
|
20
|
+
schedule:
|
|
21
|
+
- cron: "17 3 * * 1"
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
|
|
27
|
+
concurrency:
|
|
28
|
+
group: cache-prime-${{ github.ref }}
|
|
29
|
+
cancel-in-progress: true
|
|
30
|
+
|
|
31
|
+
env:
|
|
32
|
+
CARGO_TERM_COLOR: always
|
|
33
|
+
CARGO_INCREMENTAL: "0"
|
|
34
|
+
CARGO_PROFILE_DEV_DEBUG: "0"
|
|
35
|
+
CARGO_PROFILE_TEST_DEBUG: "0"
|
|
36
|
+
|
|
37
|
+
jobs:
|
|
38
|
+
rust-dependencies:
|
|
39
|
+
name: Rust dependencies (${{ matrix.os }})
|
|
40
|
+
runs-on: ${{ matrix.os }}
|
|
41
|
+
strategy:
|
|
42
|
+
fail-fast: false
|
|
43
|
+
matrix:
|
|
44
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
47
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
48
|
+
with:
|
|
49
|
+
toolchain: stable
|
|
50
|
+
- name: Install OpenBLAS (Ubuntu)
|
|
51
|
+
if: matrix.os == 'ubuntu-latest'
|
|
52
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
53
|
+
- name: Set OpenBLAS target (macOS)
|
|
54
|
+
if: matrix.os == 'macos-latest'
|
|
55
|
+
run: echo "OPENBLAS_TARGET=ARMV8" >> "$GITHUB_ENV"
|
|
56
|
+
- name: Cache Rust dependencies
|
|
57
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
58
|
+
with:
|
|
59
|
+
shared-key: ci-v2-${{ runner.os }}-rust-test
|
|
60
|
+
cache-workspace-crates: ${{ runner.os != 'Linux' }}
|
|
61
|
+
- name: Compile canonical test dependencies
|
|
62
|
+
if: matrix.os == 'ubuntu-latest'
|
|
63
|
+
run: cargo test --locked --no-run
|
|
64
|
+
- name: Compile consolidated test dependencies
|
|
65
|
+
if: matrix.os != 'ubuntu-latest'
|
|
66
|
+
run: python scripts/ci/lme_ci.py consolidated-test --no-run
|
|
67
|
+
|
|
68
|
+
production-dependencies:
|
|
69
|
+
name: Production-load dependencies (ubuntu)
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
73
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
74
|
+
with:
|
|
75
|
+
toolchain: stable
|
|
76
|
+
- name: Install OpenBLAS
|
|
77
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
78
|
+
- name: Cache production-load Rust dependencies
|
|
79
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
80
|
+
with:
|
|
81
|
+
shared-key: ci-v2-${{ runner.os }}-rust-release
|
|
82
|
+
cache-workspace-crates: true
|
|
83
|
+
- name: Compile production-load dependencies
|
|
84
|
+
run: cargo test --release --locked --test test_production_load --no-run
|
|
85
|
+
|
|
86
|
+
python-dependencies:
|
|
87
|
+
name: Python dependencies (${{ matrix.os }})
|
|
88
|
+
runs-on: ${{ matrix.os }}
|
|
89
|
+
strategy:
|
|
90
|
+
fail-fast: false
|
|
91
|
+
matrix:
|
|
92
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
95
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
96
|
+
with:
|
|
97
|
+
toolchain: stable
|
|
98
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
99
|
+
with:
|
|
100
|
+
python-version: "3.11"
|
|
101
|
+
- name: Install OpenBLAS (Ubuntu)
|
|
102
|
+
if: matrix.os == 'ubuntu-latest'
|
|
103
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
104
|
+
- name: Set OpenBLAS target (macOS)
|
|
105
|
+
if: matrix.os == 'macos-latest'
|
|
106
|
+
run: echo "OPENBLAS_TARGET=ARMV8" >> "$GITHUB_ENV"
|
|
107
|
+
- name: Cache Python Rust dependencies
|
|
108
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
109
|
+
with:
|
|
110
|
+
shared-key: ci-${{ runner.os }}-python
|
|
111
|
+
workspaces: python -> target
|
|
112
|
+
- name: Compile Python binding dependencies
|
|
113
|
+
if: matrix.os != 'macos-latest'
|
|
114
|
+
env:
|
|
115
|
+
PYO3_PYTHON: python
|
|
116
|
+
run: cargo build --release --manifest-path python/Cargo.toml
|
|
117
|
+
- name: Compile Python binding dependencies (macOS)
|
|
118
|
+
if: matrix.os == 'macos-latest'
|
|
119
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1
|
|
120
|
+
with:
|
|
121
|
+
args: --release --out python/dist --manifest-path python/Cargo.toml
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# Automatic runs: pull requests and v* release tags. Use workflow_dispatch for
|
|
4
|
+
# an intentional full check on any branch (Actions → CI → Run workflow).
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
pull_request:
|
|
8
|
+
push:
|
|
9
|
+
tags:
|
|
10
|
+
- "v*"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
env:
|
|
21
|
+
CARGO_TERM_COLOR: always
|
|
22
|
+
CARGO_INCREMENTAL: "0"
|
|
23
|
+
CARGO_PROFILE_DEV_DEBUG: "0"
|
|
24
|
+
CARGO_PROFILE_TEST_DEBUG: "0"
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
release-policy:
|
|
28
|
+
name: Release policy checks
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
32
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
33
|
+
with:
|
|
34
|
+
python-version: "3.11"
|
|
35
|
+
- name: Validate legal notices and provenance
|
|
36
|
+
run: python3 scripts/ci/lme_ci.py legal
|
|
37
|
+
- name: Validate Markdown links
|
|
38
|
+
run: python3 scripts/ci/lme_ci.py docs-links
|
|
39
|
+
- name: Validate completion score claims
|
|
40
|
+
run: python3 scripts/ci/lme_ci.py completion-check
|
|
41
|
+
|
|
42
|
+
security-audit:
|
|
43
|
+
name: Dependency security audit
|
|
44
|
+
permissions:
|
|
45
|
+
contents: read
|
|
46
|
+
uses: ./.github/workflows/audit.yml
|
|
47
|
+
|
|
48
|
+
rust-ubuntu:
|
|
49
|
+
name: Rust validation (ubuntu)
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
53
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
54
|
+
with:
|
|
55
|
+
toolchain: stable
|
|
56
|
+
- name: Install OpenBLAS
|
|
57
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
58
|
+
- name: Cache Rust dependencies
|
|
59
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
60
|
+
with:
|
|
61
|
+
shared-key: ci-v2-${{ runner.os }}-rust-test
|
|
62
|
+
save-if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/master' }}
|
|
63
|
+
- name: rustfmt --check
|
|
64
|
+
id: rustfmt
|
|
65
|
+
continue-on-error: true
|
|
66
|
+
run: python3 scripts/ci/lme_ci.py fmt-check
|
|
67
|
+
- name: clippy
|
|
68
|
+
id: clippy
|
|
69
|
+
continue-on-error: true
|
|
70
|
+
run: python3 scripts/ci/lme_ci.py clippy
|
|
71
|
+
- name: cargo check --workspace --all-targets
|
|
72
|
+
id: check
|
|
73
|
+
continue-on-error: true
|
|
74
|
+
run: python3 scripts/ci/lme_ci.py check
|
|
75
|
+
- name: Run tests
|
|
76
|
+
id: tests
|
|
77
|
+
continue-on-error: true
|
|
78
|
+
run: python3 scripts/ci/lme_ci.py build-test
|
|
79
|
+
- name: Run doctests
|
|
80
|
+
id: doctests
|
|
81
|
+
continue-on-error: true
|
|
82
|
+
run: python3 scripts/ci/lme_ci.py doctest
|
|
83
|
+
- name: Build documentation
|
|
84
|
+
id: docs
|
|
85
|
+
continue-on-error: true
|
|
86
|
+
run: python3 scripts/ci/lme_ci.py doc
|
|
87
|
+
- name: Report Rust validation failures
|
|
88
|
+
if: >-
|
|
89
|
+
${{ !cancelled() && (
|
|
90
|
+
steps.rustfmt.outcome == 'failure' ||
|
|
91
|
+
steps.clippy.outcome == 'failure' ||
|
|
92
|
+
steps.check.outcome == 'failure' ||
|
|
93
|
+
steps.tests.outcome == 'failure' ||
|
|
94
|
+
steps.doctests.outcome == 'failure' ||
|
|
95
|
+
steps.docs.outcome == 'failure'
|
|
96
|
+
) }}
|
|
97
|
+
run: exit 1
|
|
98
|
+
|
|
99
|
+
test:
|
|
100
|
+
name: Test (${{ matrix.os }})
|
|
101
|
+
runs-on: ${{ matrix.os }}
|
|
102
|
+
strategy:
|
|
103
|
+
fail-fast: false
|
|
104
|
+
matrix:
|
|
105
|
+
os: [windows-latest, macos-latest]
|
|
106
|
+
|
|
107
|
+
steps:
|
|
108
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
109
|
+
|
|
110
|
+
- name: Install Rust toolchain
|
|
111
|
+
uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
112
|
+
with:
|
|
113
|
+
toolchain: stable
|
|
114
|
+
|
|
115
|
+
- name: Cache Rust dependencies
|
|
116
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
117
|
+
with:
|
|
118
|
+
shared-key: ci-v2-${{ runner.os }}-rust-test
|
|
119
|
+
cache-workspace-crates: true
|
|
120
|
+
save-if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/master' }}
|
|
121
|
+
|
|
122
|
+
- name: Set OpenBLAS target (macOS)
|
|
123
|
+
if: matrix.os == 'macos-latest'
|
|
124
|
+
run: echo "OPENBLAS_TARGET=ARMV8" >> "$GITHUB_ENV"
|
|
125
|
+
|
|
126
|
+
- name: Run tests
|
|
127
|
+
run: python scripts/ci/lme_ci.py consolidated-test
|
|
128
|
+
|
|
129
|
+
production-load:
|
|
130
|
+
name: Production load & perf gates (ubuntu, release)
|
|
131
|
+
runs-on: ubuntu-latest
|
|
132
|
+
steps:
|
|
133
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
134
|
+
|
|
135
|
+
- name: Install Rust toolchain
|
|
136
|
+
uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
137
|
+
with:
|
|
138
|
+
toolchain: stable
|
|
139
|
+
|
|
140
|
+
- name: Install OpenBLAS (Ubuntu)
|
|
141
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
142
|
+
|
|
143
|
+
- name: Restore Rust dependencies
|
|
144
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
145
|
+
with:
|
|
146
|
+
shared-key: ci-v2-${{ runner.os }}-rust-release
|
|
147
|
+
cache-workspace-crates: true
|
|
148
|
+
save-if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/master' }}
|
|
149
|
+
|
|
150
|
+
- name: Production load tests (smoke + release wall-clock gates)
|
|
151
|
+
run: cargo test --release --locked --verbose --test test_production_load
|
|
152
|
+
|
|
153
|
+
- name: Heavy production load tests (ignored)
|
|
154
|
+
if: github.event_name != 'pull_request'
|
|
155
|
+
run: cargo test --release --locked --verbose --test test_production_load -- --ignored --test-threads=1
|
|
156
|
+
|
|
157
|
+
python-bindings-versions:
|
|
158
|
+
name: Python ${{ matrix.python-version }} (ubuntu)
|
|
159
|
+
runs-on: ubuntu-latest
|
|
160
|
+
strategy:
|
|
161
|
+
fail-fast: false
|
|
162
|
+
matrix:
|
|
163
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
164
|
+
steps:
|
|
165
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
166
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
167
|
+
with:
|
|
168
|
+
toolchain: stable
|
|
169
|
+
- name: Install OpenBLAS
|
|
170
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
171
|
+
- name: Cache Python Rust dependencies
|
|
172
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
173
|
+
with:
|
|
174
|
+
shared-key: ci-${{ runner.os }}-python
|
|
175
|
+
workspaces: python -> target
|
|
176
|
+
save-if: ${{ matrix.python-version == '3.11' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/master') }}
|
|
177
|
+
- name: Set up uv
|
|
178
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
179
|
+
with:
|
|
180
|
+
python-version: ${{ matrix.python-version }}
|
|
181
|
+
enable-cache: true
|
|
182
|
+
cache-dependency-glob: "python/uv.lock"
|
|
183
|
+
|
|
184
|
+
- name: Python bindings (canonical editable identity + isolated wheel)
|
|
185
|
+
if: matrix.python-version == '3.11'
|
|
186
|
+
run: python scripts/ci/lme_ci.py python --python-version ${{ matrix.python-version }} --examples
|
|
187
|
+
|
|
188
|
+
- name: Python bindings (isolated wheel compatibility)
|
|
189
|
+
if: matrix.python-version != '3.11'
|
|
190
|
+
run: python scripts/ci/lme_ci.py python --python-version ${{ matrix.python-version }} --wheel-only
|
|
191
|
+
|
|
192
|
+
python-bindings-os:
|
|
193
|
+
name: Python 3.11 (${{ matrix.os }})
|
|
194
|
+
runs-on: ${{ matrix.os }}
|
|
195
|
+
strategy:
|
|
196
|
+
fail-fast: false
|
|
197
|
+
matrix:
|
|
198
|
+
os: [windows-latest, macos-latest]
|
|
199
|
+
steps:
|
|
200
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
201
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
202
|
+
with:
|
|
203
|
+
toolchain: stable
|
|
204
|
+
- name: Set OpenBLAS target (macOS)
|
|
205
|
+
if: matrix.os == 'macos-latest'
|
|
206
|
+
run: echo "OPENBLAS_TARGET=ARMV8" >> "$GITHUB_ENV"
|
|
207
|
+
- name: Cache Python Rust dependencies
|
|
208
|
+
uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
209
|
+
with:
|
|
210
|
+
shared-key: ci-${{ runner.os }}-python
|
|
211
|
+
workspaces: python -> target
|
|
212
|
+
save-if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/master' }}
|
|
213
|
+
- name: Set up uv
|
|
214
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
215
|
+
with:
|
|
216
|
+
python-version: "3.11"
|
|
217
|
+
enable-cache: true
|
|
218
|
+
cache-dependency-glob: "python/uv.lock"
|
|
219
|
+
- name: Python bindings (isolated wheel OS compatibility)
|
|
220
|
+
run: python scripts/ci/lme_ci.py python --python-version 3.11 --wheel-only --examples
|
|
221
|
+
|
|
222
|
+
publish-crate:
|
|
223
|
+
name: Publish Rust crate after CI
|
|
224
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
225
|
+
needs:
|
|
226
|
+
- release-policy
|
|
227
|
+
- security-audit
|
|
228
|
+
- rust-ubuntu
|
|
229
|
+
- test
|
|
230
|
+
- production-load
|
|
231
|
+
- python-bindings-versions
|
|
232
|
+
- python-bindings-os
|
|
233
|
+
permissions:
|
|
234
|
+
contents: read
|
|
235
|
+
uses: ./.github/workflows/crate-publish-dry-run.yml
|
|
236
|
+
with:
|
|
237
|
+
publish: true
|
|
238
|
+
secrets: inherit
|
|
239
|
+
|
|
240
|
+
publish-python:
|
|
241
|
+
name: Dispatch Python release after CI
|
|
242
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
243
|
+
needs:
|
|
244
|
+
- release-policy
|
|
245
|
+
- security-audit
|
|
246
|
+
- rust-ubuntu
|
|
247
|
+
- test
|
|
248
|
+
- production-load
|
|
249
|
+
- python-bindings-versions
|
|
250
|
+
- python-bindings-os
|
|
251
|
+
permissions:
|
|
252
|
+
actions: write
|
|
253
|
+
contents: read
|
|
254
|
+
runs-on: ubuntu-latest
|
|
255
|
+
steps:
|
|
256
|
+
- name: Dispatch verified Python release
|
|
257
|
+
env:
|
|
258
|
+
GH_TOKEN: ${{ github.token }}
|
|
259
|
+
RELEASE_SHA: ${{ github.sha }}
|
|
260
|
+
RELEASE_TAG: ${{ github.ref_name }}
|
|
261
|
+
run: |
|
|
262
|
+
gh workflow run python-release.yml \
|
|
263
|
+
--repo "${GITHUB_REPOSITORY}" \
|
|
264
|
+
--ref master \
|
|
265
|
+
-f release_tag="${RELEASE_TAG}" \
|
|
266
|
+
-f release_sha="${RELEASE_SHA}" \
|
|
267
|
+
-f publish=true
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
name: Publish Rust crate
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
# cargo publish --dry-run
|
|
3
|
+
# CI calls this workflow after every release-tag validation job succeeds.
|
|
4
|
+
# Manual dispatch validates with cargo publish --dry-run and never publishes.
|
|
5
5
|
|
|
6
6
|
on:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
workflow_call:
|
|
8
|
+
inputs:
|
|
9
|
+
publish:
|
|
10
|
+
description: Publish the validated release tag to crates.io
|
|
11
|
+
required: false
|
|
12
|
+
type: boolean
|
|
13
|
+
default: false
|
|
10
14
|
workflow_dispatch:
|
|
11
15
|
|
|
12
16
|
permissions:
|
|
@@ -21,16 +25,17 @@ jobs:
|
|
|
21
25
|
name: cargo publish
|
|
22
26
|
runs-on: ubuntu-latest
|
|
23
27
|
steps:
|
|
24
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
25
29
|
|
|
26
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
30
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
|
31
|
+
with:
|
|
32
|
+
toolchain: stable
|
|
27
33
|
|
|
28
34
|
- name: Validate crate package (dry run)
|
|
29
|
-
if: github.event_name == 'workflow_dispatch'
|
|
30
35
|
run: cargo publish --dry-run --locked
|
|
31
36
|
|
|
32
37
|
- name: Publish root crate
|
|
33
|
-
if: startsWith(github.ref, 'refs/tags/')
|
|
38
|
+
if: inputs.publish && startsWith(github.ref, 'refs/tags/v')
|
|
34
39
|
env:
|
|
35
40
|
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
36
41
|
run: |
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
#
|
|
2
|
-
name: Fuzz
|
|
1
|
+
# Weekly and manually dispatched libFuzzer smoke.
|
|
2
|
+
name: Fuzz smoke
|
|
3
3
|
|
|
4
4
|
on:
|
|
5
5
|
workflow_dispatch:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "43 3 * * 0"
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: fuzz-${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
6
15
|
|
|
7
16
|
jobs:
|
|
8
17
|
libfuzzer-smoke:
|
|
@@ -13,14 +22,16 @@ jobs:
|
|
|
13
22
|
working-directory: fuzz
|
|
14
23
|
|
|
15
24
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
25
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
17
26
|
|
|
18
|
-
- uses: dtolnay/rust-toolchain@nightly
|
|
27
|
+
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # nightly
|
|
28
|
+
with:
|
|
29
|
+
toolchain: nightly
|
|
19
30
|
|
|
20
31
|
- name: Install cargo-fuzz
|
|
21
|
-
run: cargo install cargo-fuzz --locked
|
|
32
|
+
run: cargo install cargo-fuzz@0.13.2 --locked
|
|
22
33
|
|
|
23
|
-
- uses: Swatinem/rust-cache@v2
|
|
34
|
+
- uses: Swatinem/rust-cache@a45951ff880207c249adf57334cf2e9bd81d6e1e # v2
|
|
24
35
|
with:
|
|
25
36
|
workspaces: fuzz
|
|
26
37
|
|