lme-python 0.1.4__tar.gz → 0.1.8__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.1.8/.github/workflows/audit.yml +73 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/.github/workflows/benchmarks.yml +0 -61
- lme_python-0.1.8/.github/workflows/ci.yml +247 -0
- lme_python-0.1.8/.github/workflows/crate-publish-dry-run.yml +28 -0
- lme_python-0.1.8/.github/workflows/fuzz-smoke.yml +34 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/.github/workflows/python-release.yml +15 -14
- {lme_python-0.1.4 → lme_python-0.1.8}/.github/workflows/repo-metadata.yml +12 -2
- {lme_python-0.1.4 → lme_python-0.1.8}/.gitignore +3 -0
- lme_python-0.1.8/AGENTS.md +173 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/BENCHMARKS.md +1 -1
- lme_python-0.1.8/CHANGELOG.md +118 -0
- lme_python-0.1.8/CONTRIBUTING.md +176 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/Cargo.lock +13 -13
- {lme_python-0.1.4 → lme_python-0.1.8}/Cargo.toml +30 -2
- {lme_python-0.1.4 → lme_python-0.1.8}/GUIDE.md +65 -8
- {lme_python-0.1.4 → lme_python-0.1.8}/PKG-INFO +5 -1
- {lme_python-0.1.4 → lme_python-0.1.8}/README.md +13 -8
- lme_python-0.1.8/RELEASING.md +255 -0
- lme_python-0.1.8/REPO_COMPLETION_BY_AREA.md +74 -0
- lme_python-0.1.8/Taskfile.yml +108 -0
- lme_python-0.1.8/benches/bench_load_production.rs +188 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/benches/bench_math.rs +41 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/COMPARISONS.md +309 -78
- lme_python-0.1.8/comparisons/categorical_anova.R +17 -0
- lme_python-0.1.8/comparisons/categorical_anova.jl +13 -0
- lme_python-0.1.8/comparisons/categorical_anova.py +16 -0
- lme_python-0.1.8/comparisons/categorical_anova.rs +24 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_cbpp.R +15 -5
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_cbpp.jl +3 -0
- lme_python-0.1.8/comparisons/glmm_cbpp.py +66 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_cbpp.rs +8 -4
- lme_python-0.1.8/comparisons/glmm_gaussian.R +29 -0
- lme_python-0.1.8/comparisons/glmm_gaussian.jl +29 -0
- lme_python-0.1.8/comparisons/glmm_gaussian.py +54 -0
- lme_python-0.1.8/comparisons/glmm_gaussian.rs +46 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_grouseticks.rs +1 -1
- lme_python-0.1.8/comparisons/lmer_weighted.R +28 -0
- lme_python-0.1.8/comparisons/lmer_weighted.jl +37 -0
- lme_python-0.1.8/comparisons/lmer_weighted.py +63 -0
- lme_python-0.1.8/comparisons/lmer_weighted.rs +51 -0
- lme_python-0.1.8/comparisons/lmm_dyestuff.py +33 -0
- lme_python-0.1.8/comparisons/lmm_pastes.py +47 -0
- lme_python-0.1.8/comparisons/lmm_penicillin.py +43 -0
- lme_python-0.1.8/lefthook.yml +40 -0
- lme_python-0.1.8/mise.toml +16 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/pyproject.toml +20 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/python/Cargo.lock +28 -59
- {lme_python-0.1.4 → lme_python-0.1.8}/python/Cargo.toml +3 -2
- {lme_python-0.1.4 → lme_python-0.1.8}/python/PYTHON_GUIDE.md +42 -14
- {lme_python-0.1.4 → lme_python-0.1.8}/python/examples/glmer_cbpp.py +5 -4
- {lme_python-0.1.4 → lme_python-0.1.8}/python/examples/glmer_grouseticks.py +15 -14
- {lme_python-0.1.4 → lme_python-0.1.8}/python/examples/lm_basics.py +2 -2
- {lme_python-0.1.4 → lme_python-0.1.8}/python/examples/lmer_sleepstudy.py +9 -7
- {lme_python-0.1.4 → lme_python-0.1.8}/python/examples/model_comparison.py +22 -20
- lme_python-0.1.8/python/examples/plotting_demo/.gitignore +6 -0
- lme_python-0.1.8/python/examples/plotting_demo/README.md +129 -0
- lme_python-0.1.8/python/examples/plotting_demo/compare_plots.py +318 -0
- lme_python-0.1.8/python/examples/plotting_demo/figure_specs.py +45 -0
- lme_python-0.1.8/python/examples/plotting_demo/find_rscript.py +91 -0
- lme_python-0.1.8/python/examples/plotting_demo/numeric_overlay.py +141 -0
- lme_python-0.1.8/python/examples/plotting_demo/paths.py +14 -0
- lme_python-0.1.8/python/examples/plotting_demo/plot_demo.py +191 -0
- lme_python-0.1.8/python/examples/plotting_demo/plot_r.R +177 -0
- lme_python-0.1.8/python/examples/plotting_demo/run_all.py +65 -0
- lme_python-0.1.8/python/examples/verification_project/README.md +42 -0
- lme_python-0.1.8/python/examples/verification_project/conftest.py +8 -0
- lme_python-0.1.8/python/examples/verification_project/parity.py +193 -0
- lme_python-0.1.8/python/examples/verification_project/paths.py +14 -0
- lme_python-0.1.8/python/examples/verification_project/run.py +39 -0
- lme_python-0.1.8/python/examples/verification_project/test_parity.py +41 -0
- lme_python-0.1.8/python/lme_python.pyi +150 -0
- lme_python-0.1.8/python/requirements-ci.txt +87 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/python/src/lib.rs +638 -70
- lme_python-0.1.8/python/tests/test_api_parity.py +138 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/python/tests/test_basic.py +97 -66
- lme_python-0.1.8/scripts/ci/README.md +27 -0
- lme_python-0.1.8/scripts/ci/lme_ci.py +404 -0
- lme_python-0.1.8/scripts/ci/run.sh +30 -0
- lme_python-0.1.8/scripts/local_ci.ps1 +4 -0
- lme_python-0.1.8/scripts/local_ci.sh +4 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/run_cross_language_benchmarks.py +19 -1
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/sync_github_repo_metadata.py +35 -4
- lme_python-0.1.8/src/anova.rs +235 -0
- lme_python-0.1.8/src/anova_contrasts.rs +208 -0
- lme_python-0.1.8/src/contrast.rs +266 -0
- lme_python-0.1.8/src/ddf.rs +202 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/src/formula.rs +21 -0
- lme_python-0.1.8/src/glmm_math.rs +1237 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/src/kenward_roger.rs +11 -1
- lme_python-0.1.8/src/kr_modcomp.rs +327 -0
- lme_python-0.1.8/src/kr_vcov_adj.rs +296 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/src/lib.rs +228 -28
- {lme_python-0.1.4 → lme_python-0.1.8}/src/model_matrix.rs +254 -14
- lme_python-0.1.8/src/nlmm/fit.rs +528 -0
- lme_python-0.1.8/src/nlmm/formula.rs +124 -0
- lme_python-0.1.8/src/nlmm/mod.rs +37 -0
- lme_python-0.1.8/src/nlmm/sslogis.rs +37 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/src/optimizer.rs +94 -65
- {lme_python-0.1.4 → lme_python-0.1.8}/src/robust.rs +8 -2
- {lme_python-0.1.4 → lme_python-0.1.8}/src/satterthwaite.rs +32 -22
- lme_python-0.1.8/tests/categorical_anova_test.rs +42 -0
- lme_python-0.1.8/tests/data/golden_parity_manifest.json +466 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/intercept_only.json +2 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/mock_ml.json +2 -0
- lme_python-0.1.8/tests/data/orange.csv +36 -0
- lme_python-0.1.8/tests/data/orange_nlmer.json +15 -0
- lme_python-0.1.8/tests/data/pastes_cask_reml.json +17 -0
- lme_python-0.1.8/tests/data/penicillin.csv +145 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/penicillin.json +2 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/random_slopes.json +2 -0
- lme_python-0.1.8/tests/generate_test_data.R +506 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_anova.rs +6 -6
- lme_python-0.1.8/tests/test_anova_types.rs +56 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_confint_simulate.rs +13 -2
- lme_python-0.1.8/tests/test_contrast.rs +83 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_coverage_edge_cases.rs +2 -1
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_coverage_gaps.rs +3 -0
- lme_python-0.1.8/tests/test_failure_modes.rs +235 -0
- lme_python-0.1.8/tests/test_formula_stress.rs +316 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_gaps.rs +10 -3
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_glmm.rs +96 -3
- lme_python-0.1.8/tests/test_glmm_weighted.rs +64 -0
- lme_python-0.1.8/tests/test_golden_parity.rs +543 -0
- lme_python-0.1.8/tests/test_kr_modcomp_pastes.rs +51 -0
- lme_python-0.1.8/tests/test_nlmm_orange.rs +54 -0
- lme_python-0.1.8/tests/test_production_load.rs +360 -0
- lme_python-0.1.8/tests/test_statistical_identities.rs +294 -0
- lme_python-0.1.4/.github/workflows/ci.yml +0 -66
- lme_python-0.1.4/CHANGELOG.md +0 -72
- lme_python-0.1.4/CONTRIBUTING.md +0 -91
- lme_python-0.1.4/RELEASING.md +0 -185
- lme_python-0.1.4/comparisons/glmm_cbpp.py +0 -45
- lme_python-0.1.4/comparisons/lmm_dyestuff.py +0 -21
- lme_python-0.1.4/comparisons/lmm_pastes.py +0 -35
- lme_python-0.1.4/comparisons/lmm_penicillin.py +0 -35
- lme_python-0.1.4/src/anova.rs +0 -164
- lme_python-0.1.4/src/glmm_math.rs +0 -606
- lme_python-0.1.4/tests/data/penicillin.csv +0 -145
- lme_python-0.1.4/tests/generate_test_data.R +0 -231
- {lme_python-0.1.4 → lme_python-0.1.8}/LICENSE +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/comparison_chart.png +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_grouseticks.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_grouseticks.jl +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/glmm_grouseticks.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_dyestuff.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_dyestuff.jl +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_dyestuff.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_pastes.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_pastes.jl +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_pastes.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_penicillin.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_penicillin.jl +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/lmm_penicillin.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy.jl +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy_ml.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy_ml.jl +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy_ml.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/comparisons/sleepstudy_ml.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/docs/benchmarks/app.js +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/docs/benchmarks/index.html +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/docs/benchmarks/styles.css +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/docs/index.html +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/ast_explorations/test_fiasto.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/ast_explorations/test_fiasto_offset.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/build_benchmark_site.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/dump_dyestuff.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/dump_pastes.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/make_penicillin_csv.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/scripts/plot_comparisons.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/src/family.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/src/math.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/cbpp_binary.csv +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/dyestuff.csv +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/glmm_binomial.json +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/glmm_poisson.json +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/grouseticks.csv +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/mock_crossed.json +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/pastes.csv +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/data/sleepstudy.csv +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/generate_mock_data.py +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_conditional_real.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_crossed_mock.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_e2e_lmer.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_edge_cases.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_errors.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_formula.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_intercept_only.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_kenward_roger.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_ml_optimization.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_no_intercept.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_numerical_parity.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_predict.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_random_slopes.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_robust.rs +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_sandwich_math.R +0 -0
- {lme_python-0.1.4 → lme_python-0.1.8}/tests/test_satterthwaite.rs +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: Security audit
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Weekly: Mondays 12:00 UTC
|
|
6
|
+
- cron: "0 12 * * 1"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
push:
|
|
9
|
+
branches: [master]
|
|
10
|
+
paths:
|
|
11
|
+
- "**/Cargo.toml"
|
|
12
|
+
- "**/Cargo.lock"
|
|
13
|
+
- "python/pyproject.toml"
|
|
14
|
+
- "python/requirements-ci.txt"
|
|
15
|
+
pull_request:
|
|
16
|
+
branches: [master]
|
|
17
|
+
paths:
|
|
18
|
+
- "**/Cargo.toml"
|
|
19
|
+
- "**/Cargo.lock"
|
|
20
|
+
- "python/pyproject.toml"
|
|
21
|
+
- "python/requirements-ci.txt"
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
concurrency:
|
|
27
|
+
group: audit-${{ github.workflow }}-${{ github.ref }}
|
|
28
|
+
cancel-in-progress: true
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
audit:
|
|
32
|
+
name: cargo audit
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v6
|
|
36
|
+
|
|
37
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
38
|
+
|
|
39
|
+
- name: Install cargo-audit
|
|
40
|
+
uses: taiki-e/install-action@v2
|
|
41
|
+
with:
|
|
42
|
+
tool: cargo-audit@0.22.1
|
|
43
|
+
|
|
44
|
+
- name: Run cargo audit (root)
|
|
45
|
+
run: cargo audit
|
|
46
|
+
|
|
47
|
+
- name: Run cargo audit (python/)
|
|
48
|
+
working-directory: python
|
|
49
|
+
run: cargo audit
|
|
50
|
+
|
|
51
|
+
pip-audit:
|
|
52
|
+
name: pip-audit (python lockfile)
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v6
|
|
56
|
+
|
|
57
|
+
- name: Set up Python
|
|
58
|
+
uses: actions/setup-python@v6
|
|
59
|
+
with:
|
|
60
|
+
python-version: "3.11"
|
|
61
|
+
cache: pip
|
|
62
|
+
cache-dependency-path: python/requirements-ci.txt
|
|
63
|
+
|
|
64
|
+
- name: Install locked CI dependencies
|
|
65
|
+
working-directory: python
|
|
66
|
+
run: |
|
|
67
|
+
set -euo pipefail
|
|
68
|
+
python -m pip install -U pip
|
|
69
|
+
python -m pip install -r requirements-ci.txt
|
|
70
|
+
|
|
71
|
+
- name: pip-audit
|
|
72
|
+
working-directory: python
|
|
73
|
+
run: python -m pip_audit
|
|
@@ -17,7 +17,6 @@ on:
|
|
|
17
17
|
|
|
18
18
|
permissions:
|
|
19
19
|
contents: write
|
|
20
|
-
pages: write
|
|
21
20
|
id-token: write
|
|
22
21
|
|
|
23
22
|
env:
|
|
@@ -172,63 +171,3 @@ jobs:
|
|
|
172
171
|
echo "Cross-language benchmark script failed with exit code ${{ steps.cross_language_run.outputs.status }}." >&2
|
|
173
172
|
exit 1
|
|
174
173
|
|
|
175
|
-
pages:
|
|
176
|
-
name: Publish Benchmark Dashboard
|
|
177
|
-
runs-on: ubuntu-latest
|
|
178
|
-
needs:
|
|
179
|
-
- criterion
|
|
180
|
-
- cross-language
|
|
181
|
-
if: needs.criterion.result == 'success' && needs.cross-language.result == 'success' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))
|
|
182
|
-
environment:
|
|
183
|
-
name: github-pages
|
|
184
|
-
url: ${{ steps.deploy.outputs.page_url }}
|
|
185
|
-
steps:
|
|
186
|
-
- uses: actions/checkout@v6
|
|
187
|
-
|
|
188
|
-
- uses: actions/setup-python@v6
|
|
189
|
-
with:
|
|
190
|
-
python-version: "3.11"
|
|
191
|
-
|
|
192
|
-
- name: Download cross-language artifact
|
|
193
|
-
uses: actions/download-artifact@v5
|
|
194
|
-
with:
|
|
195
|
-
name: cross-language-${{ github.sha }}
|
|
196
|
-
path: site-input
|
|
197
|
-
|
|
198
|
-
- name: Resolve release URL
|
|
199
|
-
id: release_url
|
|
200
|
-
run: |
|
|
201
|
-
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
|
|
202
|
-
echo "value=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
|
|
203
|
-
else
|
|
204
|
-
echo "value=" >> "$GITHUB_OUTPUT"
|
|
205
|
-
fi
|
|
206
|
-
|
|
207
|
-
- name: Build benchmark dashboard
|
|
208
|
-
run: |
|
|
209
|
-
set -euo pipefail
|
|
210
|
-
mkdir -p site
|
|
211
|
-
cp -R docs/. site/
|
|
212
|
-
mkdir -p site/benchmarks/data
|
|
213
|
-
cross_json="$(find site-input -name 'cross-language-*.json' -print -quit)"
|
|
214
|
-
python scripts/build_benchmark_site.py \
|
|
215
|
-
--cross-language-json "$cross_json" \
|
|
216
|
-
--output-dir "site/benchmarks/data" \
|
|
217
|
-
--run-url "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" \
|
|
218
|
-
--release-url "${{ steps.release_url.outputs.value }}" \
|
|
219
|
-
--criterion-asset-name "criterion-${GITHUB_SHA}.tar.gz" \
|
|
220
|
-
--cross-language-asset-name "cross-language-${GITHUB_SHA}.json" \
|
|
221
|
-
--ref-name "${GITHUB_REF_NAME}"
|
|
222
|
-
|
|
223
|
-
- uses: actions/configure-pages@v5
|
|
224
|
-
with:
|
|
225
|
-
token: ${{ secrets.REPO_ADMIN_TOKEN != '' && secrets.REPO_ADMIN_TOKEN || github.token }}
|
|
226
|
-
enablement: ${{ secrets.REPO_ADMIN_TOKEN != '' }}
|
|
227
|
-
|
|
228
|
-
- uses: actions/upload-pages-artifact@v3
|
|
229
|
-
with:
|
|
230
|
-
path: site
|
|
231
|
-
|
|
232
|
-
- name: Deploy to GitHub Pages
|
|
233
|
-
id: deploy
|
|
234
|
-
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths-ignore:
|
|
7
|
+
- "**/*.md"
|
|
8
|
+
- "LICENSE"
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [master]
|
|
11
|
+
paths-ignore:
|
|
12
|
+
- "**/*.md"
|
|
13
|
+
- "LICENSE"
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
20
|
+
cancel-in-progress: true
|
|
21
|
+
|
|
22
|
+
env:
|
|
23
|
+
CARGO_TERM_COLOR: always
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
rust-lint:
|
|
27
|
+
name: Rust fmt & clippy
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v6
|
|
31
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
32
|
+
- name: Install OpenBLAS
|
|
33
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
34
|
+
- name: Cache cargo registry & build
|
|
35
|
+
uses: actions/cache@v5
|
|
36
|
+
with:
|
|
37
|
+
path: |
|
|
38
|
+
~/.cargo/registry
|
|
39
|
+
~/.cargo/git
|
|
40
|
+
target
|
|
41
|
+
key: ubuntu-lint-${{ hashFiles('**/Cargo.lock') }}
|
|
42
|
+
restore-keys: ubuntu-lint-
|
|
43
|
+
- name: rustfmt --check
|
|
44
|
+
run: python3 scripts/ci/lme_ci.py fmt-check
|
|
45
|
+
- name: clippy
|
|
46
|
+
run: python3 scripts/ci/lme_ci.py clippy
|
|
47
|
+
|
|
48
|
+
test:
|
|
49
|
+
name: Test (${{ matrix.os }})
|
|
50
|
+
runs-on: ${{ matrix.os }}
|
|
51
|
+
strategy:
|
|
52
|
+
fail-fast: false
|
|
53
|
+
matrix:
|
|
54
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
55
|
+
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v6
|
|
58
|
+
|
|
59
|
+
- name: Install Rust toolchain
|
|
60
|
+
uses: dtolnay/rust-toolchain@stable
|
|
61
|
+
|
|
62
|
+
- name: Install OpenBLAS (Ubuntu)
|
|
63
|
+
if: matrix.os == 'ubuntu-latest'
|
|
64
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
65
|
+
|
|
66
|
+
- name: Cache cargo registry & build
|
|
67
|
+
uses: actions/cache@v5
|
|
68
|
+
with:
|
|
69
|
+
path: |
|
|
70
|
+
~/.cargo/registry
|
|
71
|
+
~/.cargo/git
|
|
72
|
+
target
|
|
73
|
+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
74
|
+
restore-keys: ${{ runner.os }}-cargo-
|
|
75
|
+
|
|
76
|
+
- name: Set OpenBLAS target (macOS)
|
|
77
|
+
if: matrix.os == 'macos-latest'
|
|
78
|
+
run: echo "OPENBLAS_TARGET=ARMV8" >> "$GITHUB_ENV"
|
|
79
|
+
|
|
80
|
+
- name: Build
|
|
81
|
+
run: cargo build --verbose --locked
|
|
82
|
+
|
|
83
|
+
- name: Run tests
|
|
84
|
+
run: cargo test --verbose --locked
|
|
85
|
+
|
|
86
|
+
- name: Set up Python
|
|
87
|
+
uses: actions/setup-python@v6
|
|
88
|
+
with:
|
|
89
|
+
python-version: "3.11"
|
|
90
|
+
cache: pip
|
|
91
|
+
cache-dependency-path: python/requirements-ci.txt
|
|
92
|
+
|
|
93
|
+
- name: Python bindings (maturin develop, pytest, wheel install, pytest)
|
|
94
|
+
working-directory: python
|
|
95
|
+
shell: bash
|
|
96
|
+
run: |
|
|
97
|
+
set -euo pipefail
|
|
98
|
+
python -m venv .venv
|
|
99
|
+
if [ -f .venv/Scripts/python.exe ]; then
|
|
100
|
+
VPY=.venv/Scripts/python.exe
|
|
101
|
+
else
|
|
102
|
+
VPY=.venv/bin/python
|
|
103
|
+
fi
|
|
104
|
+
"$VPY" -m pip install -U pip
|
|
105
|
+
"$VPY" -m pip install -r requirements-ci.txt
|
|
106
|
+
"$VPY" -m maturin develop --release
|
|
107
|
+
"$VPY" -m pytest tests/ -v
|
|
108
|
+
"$VPY" -m maturin build --release -o dist
|
|
109
|
+
shopt -s nullglob
|
|
110
|
+
wheels=(dist/lme_python-*.whl)
|
|
111
|
+
if [ ${#wheels[@]} -eq 0 ]; then
|
|
112
|
+
echo "No wheel found under python/dist"
|
|
113
|
+
ls -la dist 2>/dev/null || true
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
"$VPY" -m pip install --force-reinstall "${wheels[0]}"
|
|
117
|
+
"$VPY" -m pytest tests/ -v
|
|
118
|
+
|
|
119
|
+
rust-all-targets:
|
|
120
|
+
name: Rust check (all targets)
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
steps:
|
|
123
|
+
- uses: actions/checkout@v6
|
|
124
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
125
|
+
- name: Install OpenBLAS
|
|
126
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
127
|
+
- name: Cache cargo registry & build
|
|
128
|
+
uses: actions/cache@v5
|
|
129
|
+
with:
|
|
130
|
+
path: |
|
|
131
|
+
~/.cargo/registry
|
|
132
|
+
~/.cargo/git
|
|
133
|
+
target
|
|
134
|
+
key: ubuntu-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
135
|
+
restore-keys: ubuntu-cargo-
|
|
136
|
+
- name: cargo check --workspace --all-targets
|
|
137
|
+
run: cargo check --workspace --all-targets --locked -v
|
|
138
|
+
|
|
139
|
+
production-load:
|
|
140
|
+
name: Production load & perf gates (ubuntu, release)
|
|
141
|
+
runs-on: ubuntu-latest
|
|
142
|
+
steps:
|
|
143
|
+
- uses: actions/checkout@v6
|
|
144
|
+
|
|
145
|
+
- name: Install Rust toolchain
|
|
146
|
+
uses: dtolnay/rust-toolchain@stable
|
|
147
|
+
|
|
148
|
+
- name: Install OpenBLAS (Ubuntu)
|
|
149
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
150
|
+
|
|
151
|
+
- name: Cache cargo registry & build
|
|
152
|
+
uses: actions/cache@v5
|
|
153
|
+
with:
|
|
154
|
+
path: |
|
|
155
|
+
~/.cargo/registry
|
|
156
|
+
~/.cargo/git
|
|
157
|
+
target
|
|
158
|
+
key: ubuntu-prodload-${{ hashFiles('**/Cargo.lock') }}
|
|
159
|
+
restore-keys: ubuntu-prodload-
|
|
160
|
+
|
|
161
|
+
- name: Production load tests (smoke + release wall-clock gates)
|
|
162
|
+
run: cargo test --release --locked --verbose --test test_production_load
|
|
163
|
+
|
|
164
|
+
- name: Heavy production load tests (ignored)
|
|
165
|
+
run: cargo test --release --locked --verbose --test test_production_load -- --ignored --test-threads=1
|
|
166
|
+
|
|
167
|
+
rust-doctests:
|
|
168
|
+
name: Rust doctests
|
|
169
|
+
runs-on: ubuntu-latest
|
|
170
|
+
steps:
|
|
171
|
+
- uses: actions/checkout@v6
|
|
172
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
173
|
+
- name: Install OpenBLAS
|
|
174
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
175
|
+
- name: Cache cargo registry & build
|
|
176
|
+
uses: actions/cache@v5
|
|
177
|
+
with:
|
|
178
|
+
path: |
|
|
179
|
+
~/.cargo/registry
|
|
180
|
+
~/.cargo/git
|
|
181
|
+
target
|
|
182
|
+
key: ubuntu-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
183
|
+
restore-keys: ubuntu-cargo-
|
|
184
|
+
- name: cargo test --doc
|
|
185
|
+
run: cargo test --doc --locked --verbose
|
|
186
|
+
|
|
187
|
+
python-bindings-versions:
|
|
188
|
+
name: Python ${{ matrix.python-version }} (ubuntu)
|
|
189
|
+
runs-on: ubuntu-latest
|
|
190
|
+
strategy:
|
|
191
|
+
fail-fast: false
|
|
192
|
+
matrix:
|
|
193
|
+
python-version: ["3.10", "3.12", "3.13"]
|
|
194
|
+
steps:
|
|
195
|
+
- uses: actions/checkout@v6
|
|
196
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
197
|
+
- name: Install OpenBLAS
|
|
198
|
+
run: sudo apt-get update && sudo apt-get install -y libopenblas-dev
|
|
199
|
+
- name: Cache cargo registry & build
|
|
200
|
+
uses: actions/cache@v5
|
|
201
|
+
with:
|
|
202
|
+
path: |
|
|
203
|
+
~/.cargo/registry
|
|
204
|
+
~/.cargo/git
|
|
205
|
+
target
|
|
206
|
+
key: ubuntu-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
207
|
+
restore-keys: ubuntu-cargo-
|
|
208
|
+
- name: Set up Python
|
|
209
|
+
uses: actions/setup-python@v6
|
|
210
|
+
with:
|
|
211
|
+
python-version: ${{ matrix.python-version }}
|
|
212
|
+
cache: pip
|
|
213
|
+
cache-dependency-path: python/requirements-ci.txt
|
|
214
|
+
- name: Python bindings (maturin develop, pytest, wheel install, pytest)
|
|
215
|
+
working-directory: python
|
|
216
|
+
shell: bash
|
|
217
|
+
run: |
|
|
218
|
+
set -euo pipefail
|
|
219
|
+
python -m venv .venv
|
|
220
|
+
if [ -f .venv/Scripts/python.exe ]; then
|
|
221
|
+
VPY=.venv/Scripts/python.exe
|
|
222
|
+
else
|
|
223
|
+
VPY=.venv/bin/python
|
|
224
|
+
fi
|
|
225
|
+
"$VPY" -m pip install -U pip
|
|
226
|
+
"$VPY" -m pip install -r requirements-ci.txt
|
|
227
|
+
"$VPY" -m maturin develop --release
|
|
228
|
+
"$VPY" -m pytest tests/ -v
|
|
229
|
+
"$VPY" -m maturin build --release -o dist
|
|
230
|
+
shopt -s nullglob
|
|
231
|
+
wheels=(dist/lme_python-*.whl)
|
|
232
|
+
if [ ${#wheels[@]} -eq 0 ]; then
|
|
233
|
+
echo "No wheel found under python/dist"
|
|
234
|
+
ls -la dist 2>/dev/null || true
|
|
235
|
+
exit 1
|
|
236
|
+
fi
|
|
237
|
+
"$VPY" -m pip install --force-reinstall "${wheels[0]}"
|
|
238
|
+
"$VPY" -m pytest tests/ -v
|
|
239
|
+
|
|
240
|
+
docs:
|
|
241
|
+
name: Build docs
|
|
242
|
+
runs-on: ubuntu-latest
|
|
243
|
+
steps:
|
|
244
|
+
- uses: actions/checkout@v6
|
|
245
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
246
|
+
- name: Build documentation
|
|
247
|
+
run: cargo doc --no-deps --verbose --locked
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Crate publish (dry-run)
|
|
2
|
+
|
|
3
|
+
# Verifies `cargo publish` packaging (metadata, README, excluded files) without uploading.
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: publish-dry-run-${{ github.workflow }}-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
dry-run:
|
|
20
|
+
name: cargo publish --dry-run
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v6
|
|
24
|
+
|
|
25
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
26
|
+
|
|
27
|
+
- name: Dry-run publish (root crate)
|
|
28
|
+
run: cargo publish --dry-run --locked
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Manual libFuzzer smoke (long compile + short run). Trigger from the Actions tab.
|
|
2
|
+
name: Fuzz (manual)
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
libfuzzer-smoke:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
timeout-minutes: 120
|
|
11
|
+
defaults:
|
|
12
|
+
run:
|
|
13
|
+
working-directory: fuzz
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: dtolnay/rust-toolchain@nightly
|
|
19
|
+
|
|
20
|
+
- name: Install cargo-fuzz
|
|
21
|
+
run: cargo install cargo-fuzz --locked
|
|
22
|
+
|
|
23
|
+
- uses: Swatinem/rust-cache@v2
|
|
24
|
+
with:
|
|
25
|
+
workspaces: fuzz
|
|
26
|
+
|
|
27
|
+
- name: Build fuzz targets
|
|
28
|
+
run: cargo fuzz build formula_parse && cargo fuzz build formula_pipeline
|
|
29
|
+
|
|
30
|
+
- name: Run formula_parse
|
|
31
|
+
run: cargo fuzz run formula_parse corpus/formula_parse -- -runs=15000 -max_len=16384
|
|
32
|
+
|
|
33
|
+
- name: Run formula_pipeline
|
|
34
|
+
run: cargo fuzz run formula_pipeline corpus/formula_parse -- -runs=15000 -max_len=16384
|
|
@@ -23,8 +23,8 @@ jobs:
|
|
|
23
23
|
matrix:
|
|
24
24
|
target: [x86_64, aarch64]
|
|
25
25
|
steps:
|
|
26
|
-
- uses: actions/checkout@
|
|
27
|
-
- uses: actions/setup-python@
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
|
+
- uses: actions/setup-python@v6
|
|
28
28
|
with:
|
|
29
29
|
python-version: '3.10'
|
|
30
30
|
- name: Build wheels
|
|
@@ -44,7 +44,7 @@ jobs:
|
|
|
44
44
|
CFLAGS: "-std=gnu99"
|
|
45
45
|
CFLAGS_aarch64_unknown_linux_gnu: "-std=gnu99"
|
|
46
46
|
- name: Upload wheels
|
|
47
|
-
uses: actions/upload-artifact@
|
|
47
|
+
uses: actions/upload-artifact@v7
|
|
48
48
|
with:
|
|
49
49
|
name: wheels-linux-${{ matrix.target }}
|
|
50
50
|
path: dist
|
|
@@ -55,8 +55,8 @@ jobs:
|
|
|
55
55
|
matrix:
|
|
56
56
|
target: [x64]
|
|
57
57
|
steps:
|
|
58
|
-
- uses: actions/checkout@
|
|
59
|
-
- uses: actions/setup-python@
|
|
58
|
+
- uses: actions/checkout@v6
|
|
59
|
+
- uses: actions/setup-python@v6
|
|
60
60
|
with:
|
|
61
61
|
python-version: '3.10'
|
|
62
62
|
architecture: ${{ matrix.target }}
|
|
@@ -67,7 +67,7 @@ jobs:
|
|
|
67
67
|
args: --release --out dist --manifest-path python/Cargo.toml
|
|
68
68
|
sccache: 'true'
|
|
69
69
|
- name: Upload wheels
|
|
70
|
-
uses: actions/upload-artifact@
|
|
70
|
+
uses: actions/upload-artifact@v7
|
|
71
71
|
with:
|
|
72
72
|
name: wheels-windows-${{ matrix.target }}
|
|
73
73
|
path: dist
|
|
@@ -78,12 +78,13 @@ jobs:
|
|
|
78
78
|
matrix:
|
|
79
79
|
target: [x86_64, aarch64]
|
|
80
80
|
steps:
|
|
81
|
-
- uses: actions/checkout@
|
|
82
|
-
- uses: actions/setup-python@
|
|
81
|
+
- uses: actions/checkout@v6
|
|
82
|
+
- uses: actions/setup-python@v6
|
|
83
83
|
with:
|
|
84
84
|
python-version: '3.10'
|
|
85
|
-
- name:
|
|
86
|
-
|
|
85
|
+
- name: Set OpenBLAS target (Apple Silicon wheel)
|
|
86
|
+
if: matrix.target == 'aarch64'
|
|
87
|
+
run: echo "OPENBLAS_TARGET=ARMV8" >> "$GITHUB_ENV"
|
|
87
88
|
- name: Build wheels
|
|
88
89
|
uses: PyO3/maturin-action@v1
|
|
89
90
|
with:
|
|
@@ -91,7 +92,7 @@ jobs:
|
|
|
91
92
|
args: --release --out dist --manifest-path python/Cargo.toml
|
|
92
93
|
sccache: 'true'
|
|
93
94
|
- name: Upload wheels
|
|
94
|
-
uses: actions/upload-artifact@
|
|
95
|
+
uses: actions/upload-artifact@v7
|
|
95
96
|
with:
|
|
96
97
|
name: wheels-macos-${{ matrix.target }}
|
|
97
98
|
path: dist
|
|
@@ -99,14 +100,14 @@ jobs:
|
|
|
99
100
|
sdist:
|
|
100
101
|
runs-on: ubuntu-latest
|
|
101
102
|
steps:
|
|
102
|
-
- uses: actions/checkout@
|
|
103
|
+
- uses: actions/checkout@v6
|
|
103
104
|
- name: Build sdist
|
|
104
105
|
uses: PyO3/maturin-action@v1
|
|
105
106
|
with:
|
|
106
107
|
command: sdist
|
|
107
108
|
args: --out dist --manifest-path python/Cargo.toml
|
|
108
109
|
- name: Upload sdist
|
|
109
|
-
uses: actions/upload-artifact@
|
|
110
|
+
uses: actions/upload-artifact@v7
|
|
110
111
|
with:
|
|
111
112
|
name: wheels-sdist
|
|
112
113
|
path: dist
|
|
@@ -122,7 +123,7 @@ jobs:
|
|
|
122
123
|
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
|
123
124
|
contents: write # needed to create GitHub Release
|
|
124
125
|
steps:
|
|
125
|
-
- uses: actions/download-artifact@
|
|
126
|
+
- uses: actions/download-artifact@v7
|
|
126
127
|
with:
|
|
127
128
|
path: dist
|
|
128
129
|
pattern: wheels-*
|
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
sync:
|
|
17
17
|
runs-on: ubuntu-latest
|
|
18
18
|
steps:
|
|
19
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
20
|
|
|
21
21
|
- name: Verify admin token is configured
|
|
22
22
|
env:
|
|
@@ -24,10 +24,20 @@ jobs:
|
|
|
24
24
|
run: |
|
|
25
25
|
if [ -z "$REPO_ADMIN_TOKEN" ]; then
|
|
26
26
|
echo "REPO_ADMIN_TOKEN is not set."
|
|
27
|
-
echo "Create a fine-grained PAT
|
|
27
|
+
echo "Create a fine-grained PAT with repository Administration: Read and write."
|
|
28
|
+
echo "Add it under Settings → Secrets and variables → Actions → REPO_ADMIN_TOKEN."
|
|
28
29
|
exit 1
|
|
29
30
|
fi
|
|
30
31
|
|
|
32
|
+
- name: Dry-run metadata payload
|
|
33
|
+
run: python scripts/sync_github_repo_metadata.py --dry-run
|
|
34
|
+
|
|
35
|
+
- name: Verify admin token is valid
|
|
36
|
+
env:
|
|
37
|
+
REPO_ADMIN_TOKEN: ${{ secrets.REPO_ADMIN_TOKEN }}
|
|
38
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
39
|
+
run: python scripts/sync_github_repo_metadata.py --verify-token
|
|
40
|
+
|
|
31
41
|
- name: Sync repository metadata
|
|
32
42
|
env:
|
|
33
43
|
REPO_ADMIN_TOKEN: ${{ secrets.REPO_ADMIN_TOKEN }}
|