Skip to content

102 separate linting workflow in ci - #103

Open
cpaniaguam wants to merge 43 commits into
mainfrom
102-separate-linting-workflow-in-ci
Open

102 separate linting workflow in ci#103
cpaniaguam wants to merge 43 commits into
mainfrom
102-separate-linting-workflow-in-ci

Conversation

@cpaniaguam

@cpaniaguam cpaniaguam commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Improvements

    • Improved reliability when saving and loading training configurations, metadata, and model outputs.
    • Enhanced training workflows with clearer validation, controlled logging, and more consistent output handling.
    • Improved error messages when requested models or configurations are unavailable.
  • Quality

    • Expanded automated formatting, linting, and test checks for more dependable releases.
    • Improved test isolation with dedicated temporary directories.
    • Refined package organization and configuration handling for greater consistency.

@cpaniaguam cpaniaguam linked an issue Jul 31, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds a dedicated Ruff workflow, updates test workflow tooling, standardizes imports and file I/O, adjusts JAX and Torch trainer logic, and improves temporary test isolation.

Changes

LANfactory maintenance updates

Layer / File(s) Summary
CI linting and test workflow updates
.github/workflows/*, pyproject.toml, .gitignore
Adds pull-request formatting and lint checks. Updates uv setup and Python matrix handling in test workflows.
Package imports and export ordering
src/lanfactory/**/__init__.py, src/lanfactory/hf/*, src/lanfactory/network_inspectors/*, tests/*
Reorders imports and public exports without changing exported symbol sets.
Serialization and temporary test data
src/lanfactory/cli/*, src/lanfactory/utils/*, tests/test_cli_utils.py, tests/conftest.py
Uses Path-based or context-managed file I/O. Tests use temporary YAML, pickle, and output paths.
JAX trainer validation and persistence
src/lanfactory/trainers/jax_mlp.py, tests/test_jax_mlp.py
Updates exception types, activation handling, training bookkeeping, MLflow error reporting, metadata persistence, and related tests.
Torch trainer loading and loop cleanup
src/lanfactory/trainers/torch_mlp.py, tests/test_torch_mlp.py
Updates pickle loading, scheduler defaults, superclass initialization, logging, batch enumeration, and unused test values.
Test isolation and helper behavior
tests/conftest.py, tests/constants.py, tests/test_mlflow_integration.py, tests/utils.py
Uses unique temporary fixture directories, adds MLflow cleanup fallback behavior, and avoids mutable default state in print_tree.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: alexanderfengler

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: separating the linting workflow in CI.
Docstring Coverage ✅ Passed Docstring coverage is 85.94% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 102-separate-linting-workflow-in-ci

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.36364% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/lanfactory/trainers/jax_mlp.py 90.90% 1 Missing and 1 partial ⚠️
Files with missing lines Coverage Δ
src/lanfactory/cli/utils.py 100.00% <100.00%> (ø)
src/lanfactory/hf/download.py 100.00% <ø> (ø)
src/lanfactory/hf/upload.py 100.00% <ø> (ø)
src/lanfactory/network_inspectors/api.py 62.50% <100.00%> (ø)
src/lanfactory/network_inspectors/config.py 100.00% <ø> (ø)
src/lanfactory/network_inspectors/loaders.py 75.00% <100.00%> (ø)
src/lanfactory/trainers/torch_mlp.py 94.13% <100.00%> (-0.05%) ⬇️
src/lanfactory/utils/mlflow_utils.py 94.23% <100.00%> (ø)
src/lanfactory/utils/util_funs.py 100.00% <100.00%> (ø)
src/lanfactory/trainers/jax_mlp.py 93.29% <90.90%> (+0.26%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI review requested due to automatic review settings July 31, 2026 21:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 30 changed files in this pull request and generated no new comments.

Suppressed comments (3)

tests/test_jax_mlp.py:47

  • The docstring still says the factory raises ValueError, but the test now asserts a TypeError. Update the docstring to match the actual exception type to avoid misleading documentation.
    """Test JaxMLPFactory raises ValueError for invalid network_config type."""

.github/workflows/run_tests.yml:64

  • The test_notebooks job no longer pins a Python version. This makes the job sensitive to GitHub runner defaults/changes and can break if the default Python is outside the supported range. Configure the Python version via setup-uv (as done in the matrix test job).
      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.12.0"

.github/workflows/linting_formatting.yml:18

  • This workflow also relies on the runner’s default Python. Pinning the Python version via setup-uv improves reproducibility and avoids CI breakage when runner defaults change.
      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.12.0"

Copilot AI review requested due to automatic review settings August 3, 2026 16:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 30 changed files in this pull request and generated no new comments.

Suppressed comments (3)

src/lanfactory/hf/init.py:11

  • Module-level imports come after assignments (DEFAULT_REPO_ID, VALID_NETWORK_TYPES), which will trigger Ruff E402 (imports not at top of file) in a default ruff configuration. Reorder so imports come immediately after the module docstring.
DEFAULT_REPO_ID = "franklab/HSSM"
VALID_NETWORK_TYPES = ("lan", "cpn", "opn")

from lanfactory.hf.download import download_model
from lanfactory.hf.model_card import (

tests/test_jax_mlp.py:47

  • The test name and assertion expect a TypeError, but the docstring still says ValueError, which is misleading when reading failures.
    """Test JaxMLPFactory raises ValueError for invalid network_config type."""

src/lanfactory/trainers/jax_mlp.py:451

  • If MLflow logging fails once, this will print an error every 100 steps for the rest of training, which can spam CI logs and slow runs. Consider disabling MLflow logging after the first failure (or gating the message behind verbose).
                    except Exception as e:
                        print(f"Failed to log metric to MLflow: {e}")

Copilot AI review requested due to automatic review settings August 4, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 48 out of 49 changed files in this pull request and generated no new comments.

Suppressed comments (3)

.github/workflows/linting_formatting.yml:19

  • The lint job doesn’t pin a Python version. Since the project requires Python >=3.12 (pyproject.toml:19), this job can become non-deterministic (or fail) depending on the runner’s default Python. Pin a supported Python version the same way the test workflow does.
      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.12.0"

tests/test_mlflow_integration.py:55

  • In teardown, the exception handler calls mlflow.set_tracking_uri(...) again without guarding it. If resetting the tracking URI ever fails, this can cause teardown to raise and mask the actual test failure; prefer a best-effort reset that cannot raise from teardown.
    src/lanfactory/cli/utils.py:104
  • yaml.safe_load() is being given raw bytes from Path(...).read_bytes(). PyYAML’s primary interface is text / file-like streams; decoding explicitly avoids cross-version quirks and makes the expected encoding clear.
def _get_train_network_config(yaml_config_path: str | Path | None = None, net_index=0):
    if yaml_config_path is not None:
        basic_config = yaml.safe_load(Path(yaml_config_path).read_bytes())
        network_type = basic_config["NETWORK_TYPE"]

Copilot AI review requested due to automatic review settings August 4, 2026 20:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 48 out of 49 changed files in this pull request and generated no new comments.

Suppressed comments (4)

src/lanfactory/trainers/jax_mlp.py:128

  • -jnp.log(1 + jnp.exp(-x)) can overflow for large-magnitude logits, which can introduce inf/nan during inference. JAX exposes a numerically stable log_sigmoid for this transformation.
            if i != (len(self.layers) - 1) or self.activations[i] != "linear":
                x = self.activation_funs[i](x)

        if (not self.train) and (self.train_output_type == "logits"):
            x = -jnp.log(1 + jnp.exp(-x))

.github/workflows/linting_formatting.yml:19

  • This workflow doesn't set a Python version. Since the project targets Python >=3.12, relying on ubuntu-latest's default Python risks CI breakage when GitHub updates the runner image. Consider explicitly setting python-version in setup-uv.
      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.12.0"

src/lanfactory/trainers/torch_mlp.py:455

  • -torch.log(1 + torch.exp(-x)) can overflow for large-magnitude logits (e.g., float32 when x is very negative), producing inf/nan. PyTorch provides a numerically stable implementation for log(sigmoid(x)).
        if self.training or self.train_output_type == "logprob":
            return self.layers[-1](x)
        elif self.train_output_type == "logits":
            return -torch.log(
                1 + torch.exp(-self.layers[-1](x))
            )  # log ( 1 / (1 + exp(-x))), where x = log(p / (1 - p))
        else:

.github/workflows/run_tests.yml:64

  • test_notebooks no longer sets python-version after removing actions/setup-python. If ubuntu-latest's default Python drifts below the supported range, this job can start failing unexpectedly. Pinning a Python version here would make the job deterministic.
      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.12.0"

…ons/setup-python-7

chore(deps): bump actions/setup-python from 6 to 7
Copilot AI review requested due to automatic review settings August 6, 2026 02:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/run_tests.yml:
- Line 64: Update the Python setup step for the test_notebooks job to use the
explicitly defined Python version "3.12" instead of the undefined
matrix.python-version reference; do not add a matrix unless this job is intended
to run across multiple versions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 60970c9d-ac41-4bae-9034-249a9a6484ee

📥 Commits

Reviewing files that changed from the base of the PR and between bbaa34d and 26df33e.

📒 Files selected for processing (2)
  • .github/workflows/run_tests.yml
  • tests/test_bayesflow_nle_export.py
💤 Files with no reviewable changes (1)
  • tests/test_bayesflow_nle_export.py

with:
version: "0.6.5"
version: "0.12.0"
python-version: ${{ matrix.python-version }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use a defined Python version for test_notebooks.

test_notebooks does not define a strategy.matrix, so ${{ matrix.python-version }} is undefined. This causes the workflow validation error reported by actionlint and prevents the notebook job from selecting its intended interpreter. Set this to "3.12" or add a matrix to this job.

Proposed fix
-          python-version: ${{ matrix.python-version }}
+          python-version: "3.12"
🧰 Tools
🪛 actionlint (1.7.12)

[error] 64-64: property "python-version" is not defined in object type {}

(expression)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/run_tests.yml at line 64, Update the Python setup step for
the test_notebooks job to use the explicitly defined Python version "3.12"
instead of the undefined matrix.python-version reference; do not add a matrix
unless this job is intended to run across multiple versions.

Source: Linters/SAST tools

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 48 out of 49 changed files in this pull request and generated 1 comment.

Suppressed comments (4)

src/lanfactory/trainers/torch_mlp.py:454

  • Computing log-sigmoid via -torch.log(1 + torch.exp(-x)) is numerically unstable for large-magnitude inputs and can overflow/underflow to inf/nan. PyTorch provides a stable implementation.
        elif self.train_output_type == "logits":
            return -torch.log(
                1 + torch.exp(-self.layers[-1](x))
            )  # log ( 1 / (1 + exp(-x))), where x = log(p / (1 - p))

.github/workflows/linting_formatting.yml:18

  • The linting workflow doesn't pin a Python version. Since the project targets Python >=3.12, relying on whatever happens to be preinstalled on ubuntu-latest can cause CI to start failing when the runner image changes.
        uses: astral-sh/setup-uv@v7
        with:
          version: "0.12.0"

tests/test_mlflow_integration.py:55

  • If resetting MLflow's tracking URI fails during cleanup, the fallback mlflow.set_tracking_uri("file:./mlruns") can also raise and fail the test teardown. Teardown should not introduce new failures; swallow errors if both resets fail.
    src/lanfactory/trainers/jax_mlp.py:128
  • Computing log-sigmoid via -jnp.log(1 + jnp.exp(-x)) is numerically unstable for large-magnitude inputs and can overflow/underflow. Use JAX's stable log_sigmoid.
        if (not self.train) and (self.train_output_type == "logits"):
            x = -jnp.log(1 + jnp.exp(-x))

with:
version: "0.6.5"
version: "0.12.0"
python-version: ${{ matrix.python-version }}
@AlexanderFengler

Copy link
Copy Markdown
Member

One small request from the drift-detection side (#107), if it's easy to fold in here.

The new linting_formatting.yml triggers on pull_request: only. #107 adds a weekly scheduled drift.yml that re-runs the repo's gates against a fresh dependency resolve of unchanged main — the point being to catch an unpinned toolchain release breaking us on a Monday rather than on the next contributor's PR. It reuses existing workflows via workflow_call rather than duplicating their steps.

Today it gets lint coverage for free, because linting lives inside run_tests.yml. Once this PR moves it out, that coverage disappears from the weekly run unless the new workflow is callable. Adding two lines here would keep it:

on:
  pull_request:
  workflow_call:

No other change needed — I'll add the lint job that calls it on my side. Worth noting because the incident that motivated the whole drift workstream was precisely an unpinned linter (ruff 0.16) breaking fresh CI on an unchanged codebase, so a scheduled lint run is one of the higher-value legs.

Also, for whenever this lands: #107 edits the same region of run_tests.yml and will conflict. Happy to rebase onto this one — just ping me. Two decisions we differ on that are worth a deliberate call rather than a conflict resolution: this PR pins setup-uv to 0.12.0 where #107 uses latest + caching, and this PR keeps the rm -rf ~/.cache/* block where #107 removes it (git history suggests it was undirected trial-and-error in June 2025, chasing a SIGILL that ssm-simulators>=0.13.1 already fixes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Separate linting workflow in CI

3 participants