Skip to content

0.1.1: fix CI, add changelog/pyproject hooks, packaging + release workflows, single-source version#1

Merged
wahln merged 2 commits into
mainfrom
develop
Jun 21, 2026
Merged

0.1.1: fix CI, add changelog/pyproject hooks, packaging + release workflows, single-source version#1
wahln merged 2 commits into
mainfrom
develop

Conversation

@wahln

@wahln wahln commented Jun 21, 2026

Copy link
Copy Markdown
Owner

0.1.1 — CI fixes, changelog/pyproject enforcement, packaging & release, single-source version

Fixes the failing main pipeline

  • test jobs: pytest --doctest-modules imports every ipax module during collection, but the JAX/CuPy autodiff and sparse adapters import their concrete library at module top level (invariant 0.1.1: fix CI, add changelog/pyproject hooks, packaging + release workflows, single-source version #1 carve-out). CI installs neither JAX nor CuPy, so collection errored. A root conftest.py now skips those adapter modules during collection unless the backend is importable (runtime dispatch already tolerated their absence).
  • lint job: mypy errored on the NumPy/SciPy sparse adapter when NumPy isn't installed in the minimal [lint] env. numpy.* joins the optional-backend ignore_missing_imports overrides.
  • Regression guard (tests/regression/test_doctest_collection_adapters.py) so a new top-level-importing adapter can't silently re-break collection.

Both failures were reproduced locally (a fresh [lint]-only venv for mypy; an import-blocker for the doctest collection) and confirmed fixed.

Pre-commit hooks

  • kacl-verify (python-kacl v0.7.3) — enforces Keep a Changelog format; CHANGELOG.md reformatted to comply.
  • validate-pyproject (v0.25) — schema-validates pyproject.toml.
  • Both are also enforced in the CI lint job.

Packaging & publishing

  • ci.yml: added develop to triggers and a package job (sdist + wheel + twine check) on main/develop/PR.
  • New release.yml (tags v* only): builds, publishes to PyPI via Trusted Publishing, and creates a GitHub release with notes from the changelog + tag annotation.

Single source of truth for the version

  • ipax.__version__ is the only literal version; pyproject.toml derives it via [tool.hatch.version] (dynamic = ["version"]).
  • README shows a dynamic PyPI version badge; hardcoded version removed from prose (README/AGENTS/CONTRIBUTING).
  • Bumped to 0.1.1.

Verification

scripts/check.py green (format/lint/types/purity/test, 780 passed); validate-pyproject and kacl-verify pass; python -m build produces ipax-0.1.1.*.

PyPI setup needed: configure a Trusted Publisher for ipax (repo wahln/ipax, workflow release.yml, environment pypi) before the first tag, or switch that job to a token.
Also note: existing README CI/RTD badges still point to niklaswahl/ipax rather than wahln/ipax — left unchanged pending confirmation.

🤖 Generated with Claude Code

Copilot AI 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.

Pull request overview

This PR targets the 0.1.1 release housekeeping: it fixes CI failures caused by optional-backend adapters being imported during --doctest-modules collection, adds enforcement hooks for changelog/pyproject validity, and introduces packaging + release automation while making the package version single-sourced from ipax.__version__.

Changes:

  • Add a root conftest.py + regression test to skip doctest collection of adapter modules when their concrete backend isn’t installed.
  • Enforce CHANGELOG.md / pyproject.toml validity via new pre-commit hooks and CI lint job checks.
  • Add packaging build job to CI and a tag-driven release.yml workflow; switch pyproject.toml to dynamic version derived from ipax/__init__.py and bump to 0.1.1.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/regression/test_doctest_collection_adapters.py Regression test ensuring adapter skip-map stays consistent with top-level concrete imports.
conftest.py Root pytest config to ignore optional-backend adapter modules during doctest collection when deps are missing.
pyproject.toml Dynamic version via Hatch, mypy overrides for optional deps, pytest doctest configuration referenced by the CI fix.
ipax/__init__.py Bump __version__ to 0.1.1 (single source of truth).
.github/workflows/ci.yml Add develop trigger, run new pre-commit checks in lint, add package build job.
.github/workflows/release.yml New release workflow for tag builds, PyPI publish (Trusted Publishing), and GitHub release notes from changelog/tag annotation.
.pre-commit-config.yaml Add validate-pyproject and kacl-verify hooks.
CHANGELOG.md Add 0.1.1 entry and Keep a Changelog-compliant formatting + link references.
README.md Add PyPI badge and remove hardcoded version prose.
CONTRIBUTING.md Remove hardcoded version in beta statement.
AGENTS.md Remove hardcoded version in beta statement.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Comment thread README.md
Comment thread conftest.py
…copes

- Ship root conftest.py in the sdist so the suite collects from an sdist
  (it now requires the root conftest for --doctest-modules).
- Fix README CI badge URL: niklaswahl/ipax -> wahln/ipax.
- Add explicit `actions: read` to the release.yml jobs that run
  actions/download-artifact (defensive least-privilege; same-run artifacts
  use the runtime token, but being explicit de-risks restricted-default orgs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wahln

wahln commented Jun 21, 2026

Copy link
Copy Markdown
Owner Author

Thanks @copilot — addressed in da15f40:

  • conftest.py not in sdist ✅ Added conftest.py to [tool.hatch.build.targets.sdist].include. Verified the built sdist now ships it, so the suite collects from an sdist.
  • README CI badge org ✅ Fixed niklaswahl/ipaxwahln/ipax.
  • download-artifact token scope (pypi-publish, github-release) ✅ Added explicit actions: read to both jobs. Note this is defensive: actions/download-artifact@v4 fetches same-run artifacts via the runtime token (ACTIONS_RUNTIME_TOKEN), not GITHUB_TOKEN, so it isn't strictly gated by permissions: — but being explicit de-risks orgs with restricted default token permissions.
  • upload-artifact needs actions: write (build job) ⚠️ Not applied. actions/upload-artifact@v4 also uploads via the runtime token, not GITHUB_TOKEN, so the workflow-level contents: read is sufficient; adding actions: write would be misleading without being necessary.

Copilot finished work on behalf of wahln June 21, 2026 11:40
@wahln wahln merged commit b56b5c7 into main Jun 21, 2026
21 checks passed
wahln added a commit that referenced this pull request Jun 22, 2026
Feasibility restoration's damped Gauss-Newton step called xp.linalg.solve on
the normal matrix without guarding the factorization. Far from feasibility a
constraint Jacobian can blow up (e.g. HS7 reaching ~1e201 at a bad iterate),
making the matrix numerically singular; numpy then raised a LinAlgError and
crashed the entire solve, while torch silently returned a non-finite step.

Treat a raised or non-finite solve as a failed Levenberg-Marquardt step: grow
the damping (up to a ceiling) and retry, exactly as for a rejected step. The
solve now degrades to a reported status instead of raising. The exception type
is backend-specific and cannot be named without importing a concrete library
(invariant #1), so it is caught broadly in this localized step.

Surfaced by the S2MPJ HS7 sweep. Regression test reproduces the exact failure
mode via a direct restore() call and asserts it returns finite and infeasible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

2 participants