fix(release): repair the publish workflow after the setup.py removal - #73
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 advertisesrequires_python: >=3.7, the value from the old setup.py.Build with
python -m buildand bump the version in pyproject.toml instead.update_version.py silently did nothing to pyproject.toml. Its patterns matched
version="x"(setup.py) andversion = 'x'(meta.yaml), but pyproject declaresversion = "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:
readmewas 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.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.twine check dist/*before upload.license_family: MITfor an Apache-2.0 package, and the README's license badge linked to LGPL-2.0.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.