Skip to content

Commit e28083f

Browse files
Transurgeonclaude
andcommitted
Remove conda from CI, use uv + system IPOPT
Replace conda-based test_nlp_solvers workflow with uv, installing IPOPT via system packages (apt on Ubuntu, brew on macOS) instead of conda-forge. Uncomment IPOPT optional dependency in pyproject.toml so uv sync --extra IPOPT works. Update installation docs in CLAUDE.md and README.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0a44098 commit e28083f

4 files changed

Lines changed: 49 additions & 35 deletions

File tree

.github/workflows/test_nlp_solvers.yml

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,30 @@ on:
1010
jobs:
1111
run_nlp_tests:
1212
runs-on: ${{ matrix.os }}
13-
defaults:
14-
run:
15-
shell: bash -l {0}
1613
strategy:
1714
fail-fast: false
1815
matrix:
1916
os: [ubuntu-latest, macos-latest]
2017
steps:
21-
- uses: actions/setup-python@v6
22-
with:
23-
python-version: "3.12"
2418
- uses: actions/checkout@v5
2519
with:
2620
submodules: recursive
27-
- name: Set up Conda
28-
uses: conda-incubator/setup-miniconda@v3
21+
- uses: astral-sh/setup-uv@v7
2922
with:
30-
activate-environment: nlp-test
31-
python-version: 3.12
32-
channels: conda-forge
33-
channel-priority: strict
34-
auto-update-conda: true
35-
miniforge-version: latest
36-
use-mamba: true
37-
- name: Install cyipopt via conda
38-
run: |
39-
conda install -y -c conda-forge cyipopt
40-
- name: Install test dependencies
41-
run: |
42-
pip install -e .
43-
pip install pytest hypothesis
23+
python-version: "3.12"
24+
enable-cache: true
25+
- name: Install IPOPT (Ubuntu)
26+
if: runner.os == 'Linux'
27+
run: sudo apt-get update && sudo apt-get install -y coinor-libipopt-dev
28+
- name: Install IPOPT (macOS)
29+
if: runner.os == 'macOS'
30+
run: brew install ipopt
31+
- name: Install dependencies
32+
run: uv sync --extra IPOPT --dev
33+
- name: Print installed solvers
34+
run: uv run python -c "import cvxpy; print(cvxpy.installed_solvers())"
4435
- name: Run nlp tests
45-
run: |
46-
pytest -s -v cvxpy/tests/nlp_tests/.
36+
run: uv run pytest -s -v cvxpy/tests/nlp_tests/
37+
38+
env:
39+
UV_SYSTEM_PYTHON: 1

CLAUDE.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ For theoretical foundation, see: [Disciplined Nonlinear Programming](https://web
1111
## Build and Development Commands
1212

1313
```bash
14-
# Install IPOPT solver (required for NLP - use conda, NOT pip)
15-
conda install -c conda-forge cyipopt
14+
# Install IPOPT solver (required for NLP)
15+
# Ubuntu/Debian:
16+
sudo apt-get install coinor-libipopt-dev
17+
# macOS:
18+
brew install ipopt
19+
# Then: uv sync --extra IPOPT (or: pip install cyipopt)
1620

17-
# Install from source (development mode)
18-
pip install -e .
21+
# Install from source (development mode) — uv or pip
22+
uv sync --all-extras --dev # preferred (uv.lock is committed)
23+
pip install -e . # alternative
1924

2025
# Install pre-commit hooks
2126
pip install pre-commit && pre-commit install
@@ -65,7 +70,7 @@ prob.solve(nlp=True, solver=cp.IPOPT, best_of=5)
6570

6671
| Solver | License | Installation |
6772
|--------|---------|--------------|
68-
| [IPOPT](https://github.com/coin-or/Ipopt) | EPL-2.0 | `conda install -c conda-forge cyipopt` (conda only — pip install is unreliable) |
73+
| [IPOPT](https://github.com/coin-or/Ipopt) | EPL-2.0 | Install system IPOPT (`apt install coinor-libipopt-dev` / `brew install ipopt`), then `pip install cyipopt` |
6974
| [Knitro](https://www.artelys.com/solvers/knitro/) | Commercial | `pip install knitro` (requires license) |
7075
| [COPT](https://www.copt.de/) | Commercial | Requires license |
7176
| [Uno](https://github.com/cuter-testing/uno) | Open source | See Uno documentation |
@@ -246,6 +251,15 @@ A common pattern is to solve with both a DCP solver (CLARABEL) and an NLP solver
246251

247252
Uses a custom build backend (`setup/build_meta.py`) that re-exports `setuptools.build_meta`. The `setup/` directory handles C extensions (cvxcore, sparsecholesky) and version management. Solver registration is in `cvxpy/reductions/solvers/defines.py` (`SOLVER_MAP_CONIC`, `SOLVER_MAP_QP`, `SOLVER_MAP_NLP`).
248253

254+
## CI Checks
255+
256+
PRs must pass these GitHub Actions workflows:
257+
- **pre-commit** — ruff linting, JSON schema validation (workflows/dependabot), actionlint, pyproject validation
258+
- **build** — full test suite on Ubuntu/macOS/Windows × Python 3.11–3.14, plus wheel builds
259+
- **test_nlp_solvers** — NLP solver tests (IPOPT via system package + uv, Knitro if available)
260+
- **test_optional_solvers** — optional solver integration tests (uses `uv sync --all-extras`)
261+
- **test_backends** — tests SCIPY and COO canonicalization backends
262+
249263
## Benchmarks
250264

251265
Benchmarks use [Airspeed Velocity](https://asv.readthedocs.io/) and live in the `benchmarks/` directory. To run locally:

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ with some rules governing how the nonsmooth functions can be used. For details,
77
## Installation
88
The installation consists of two steps.
99

10-
#### Step 1: Install IPOPT via Conda
11-
DNLP requires an NLP solver. The recommended solver is [Ipopt](https://coin-or.github.io/Ipopt/), which can be installed together with its Python interface [cyipopt](https://github.com/mechmotum/cyipopt):
10+
#### Step 1: Install IPOPT
11+
DNLP requires an NLP solver. The recommended solver is [Ipopt](https://coin-or.github.io/Ipopt/). First install the IPOPT system library, then install the Python interface [cyipopt](https://github.com/mechmotum/cyipopt):
1212
```bash
13-
conda install -c conda-forge cyipopt
13+
# Ubuntu/Debian
14+
sudo apt-get install coinor-libipopt-dev
15+
16+
# macOS
17+
brew install ipopt
18+
```
19+
Then install the Python interface:
20+
```bash
21+
pip install cyipopt
1422
```
15-
Installing cyipopt via pip may lead to issues, so we strongly recommend using the Conda installation above, even if the rest of your environment uses pip.
1623

1724
#### Step 2: Install DNLP
1825
DNLP is installed by cloning this repository and installing it locally:
@@ -56,7 +63,7 @@ print("Maximum eigenvalue: " , np.max(eigenvalues))
5663
## Supported Solvers
5764
| Solver | License | Installation |
5865
|--------|---------|--------------|
59-
| [IPOPT](https://github.com/coin-or/Ipopt) | EPL-2.0 | `conda install -c conda-forge cyipopt` |
66+
| [IPOPT](https://github.com/coin-or/Ipopt) | EPL-2.0 | Install system IPOPT (see above), then `pip install cyipopt` |
6067
| [Knitro](https://www.artelys.com/solvers/knitro/) | Commercial | `pip install knitro` (requires license) |
6168

6269
---

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ SCS = []
9494
XPRESS = ["xpress>=9.5"]
9595
DAQP = ["daqp"]
9696
KNITRO = ["knitro"]
97-
# IPOPT = ["cyipopt"]
97+
IPOPT = ["cyipopt"]
9898
testing = ["pytest", "hypothesis"]
9999
doc = ["sphinx",
100100
"sphinxcontrib.jquery",

0 commit comments

Comments
 (0)