Skip to content

fix(release): repair the publish workflow after the setup.py removal - #73

Merged
VonAlphaBisZulu merged 3 commits into
mainfrom
fix-release-pipeline
Jul 25, 2026
Merged

fix(release): repair the publish workflow after the setup.py removal#73
VonAlphaBisZulu merged 3 commits into
mainfrom
fix-release-pipeline

Conversation

@VonAlphaBisZulu

Copy link
Copy Markdown
Contributor

setup.py was deleted when the project moved to pyproject.toml, but the release workflow still referenced it in two places, so it could not have produced a release: the version-bump step would raise FileNotFoundError and the build step called python setup.py sdist bdist_wheel. The migration landed after v1.18, so the workflow has never run against a setup.py-less tree -- PyPI 1.18 still advertises requires_python: >=3.7, the value from the old setup.py.

Build with python -m build and bump the version in pyproject.toml instead.

update_version.py silently did nothing to pyproject.toml. Its patterns matched version="x" (setup.py) and version = 'x' (meta.yaml), but pyproject declares version = "x" -- spaces and double quotes -- so it rewrote the file unchanged and exited 0. A release would have been tagged and uploaded under the previous version number. It now matches all three declaration styles and exits non-zero when a file declares no version at all, so a future rename fails the run rather than shipping a stale number.

Also:

  • readme was inline text, so the PyPI project page showed a single sentence instead of README.md. Point it at the file; its images and badges already use absolute URLs, so it renders off-GitHub. Verified README.md ships in the sdist, which is what a conda-forge recipe would build from.
  • Require setuptools>=77. license = "Apache-2.0" as a bare string is PEP 639, which older setuptools rejects, and both the conda recipe and conda-forge build with --no-build-isolation against whatever setuptools the host provides.
  • Add twine check dist/* before upload.
  • The conda recipe declared license_family: MIT for an Apache-2.0 package, and the README's license badge linked to LGPL-2.0.
  • Refresh Update_version.md, which documented the setup.py flow.

Verified end to end: sdist and wheel build without isolation, metadata carries Description-Content-Type text/markdown with the full README, and the package installs from the sdist and imports.

VonAlphaBisZulu and others added 3 commits July 25, 2026 13:20
setup.py was deleted when the project moved to pyproject.toml, but the release
workflow still referenced it in two places, so it could not have produced a
release: the version-bump step would raise FileNotFoundError and the build step
called `python setup.py sdist bdist_wheel`. The migration landed after v1.18, so
the workflow has never run against a setup.py-less tree -- PyPI 1.18 still
advertises `requires_python: >=3.7`, the value from the old setup.py.

Build with `python -m build` and bump the version in pyproject.toml instead.

update_version.py silently did nothing to pyproject.toml. Its patterns matched
`version="x"` (setup.py) and `version = 'x'` (meta.yaml), but pyproject declares
`version = "x"` -- spaces and double quotes -- so it rewrote the file unchanged
and exited 0. A release would have been tagged and uploaded under the previous
version number. It now matches all three declaration styles and exits non-zero
when a file declares no version at all, so a future rename fails the run rather
than shipping a stale number.

Also:

- `readme` was inline text, so the PyPI project page showed a single sentence
  instead of README.md. Point it at the file; its images and badges already use
  absolute URLs, so it renders off-GitHub. Verified README.md ships in the sdist,
  which is what a conda-forge recipe would build from.
- Require setuptools>=77. `license = "Apache-2.0"` as a bare string is PEP 639,
  which older setuptools rejects, and both the conda recipe and conda-forge build
  with --no-build-isolation against whatever setuptools the host provides.
- Add `twine check dist/*` before upload.
- The conda recipe declared `license_family: MIT` for an Apache-2.0 package, and
  the README's license badge linked to LGPL-2.0.
- Refresh Update_version.md, which documented the setup.py flow.

Verified end to end: sdist and wheel build without isolation, metadata carries
Description-Content-Type text/markdown with the full README, and the package
installs from the sdist and imports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s the formulation

Four packages were imported directly but declared nowhere: numpy, pandas,
optlang and swiglpk. They resolved only because cobra happens to require all
four. That works today, but it means a cobra dependency change breaks
`import straindesign` with no change on our side, and the traceback points at
cobra rather than at us.

They are listed unpinned on purpose. Contributing no version constraint leaves
cobra the sole authority on which versions are resolved, so the declaration
records what we import without taking a position on versions we have no opinion
about. None of them adds install weight -- cobra pulls them in either way.

Nothing is dropped: fva() and speedy_fva are annotated `-> DataFrame` and return
'minimum'/'maximum' frames to match cobra's flux_variability_analysis, names.py
takes its status constants from optlang.interface so they stay comparable with
cobra's, networktools needs optlang's Container for the solver stub on suppressed
model copies, and swiglpk is the GLPK binding itself.

pyscipopt becomes a dependency. GLPK cannot express indicator constraints and
translates them into big-M, which is documented to give incorrect results --
glpk_interface.py:38 says so, strainDesignProblem.py:125 warns about it at
runtime, and test_07_compression.py already skips GLPK with "GLPK gives incorrect
results" while preferring SCIP as the strongest free backend. Until now the only
solver guaranteed to be present was the one that cannot state the problem
correctly. SCIP supports indicator constraints natively, is MIT/Apache licensed,
ships self-contained wheels, is on conda-forge, and is installed on every leg of
the CI matrix -- broader coverage than CPLEX, which is excluded on macOS and 3.13.

Verified: the e_coli_core gene-MCS gate on SCIP returns 455 in 7.8 s, and the KO
sets are identical to four stored gurobi references, not merely equal in count.

Also correct the license headers: "Insitute" -> "Institute" and extend the year
to 2022-2026, across the 17 modules that carry one. compression.py and
speedy_fva.py have no header and are left alone -- who holds copyright on those
is a question for their authors, not one to settle with a sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
compression.py and speedy_fva.py were the only modules in the package without
the boilerplate notice. The years are the ones the files actually date from --
compression.py first appeared 2025-12-12, speedy_fva.py 2026-03-04 -- rather than
the package-wide 2022-2026, since a copyright year that predates the file is just
wrong.

The header is a recommendation in the Apache appendix, not a condition: the
top-level LICENSE plus the License-Expression in the wheel metadata is what
satisfies the licence. These are here so the notice travels with a file that gets
copied out of the repo on its own.

Copyright holder matches the rest of the package. If either module is not MPI
work, that is a correction to make deliberately rather than by sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@VonAlphaBisZulu
VonAlphaBisZulu merged commit 2cd1bc2 into main Jul 25, 2026
20 checks passed
@VonAlphaBisZulu
VonAlphaBisZulu deleted the fix-release-pipeline branch July 25, 2026 20:49
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.

1 participant