This file documents how to create a release and publish to PyPI for moldflow-api.
The process is split into two independent stages:
- Create a GitHub Release (produces the wheel and attaches it to a tagged release)
- Publish to PyPI (uploads the wheel from the GitHub Release to PyPI)
You can create the GitHub Release first and publish to PyPI when ready.
- The canonical version source is the root
version.jsonin the repository root. - All release workflows only run on branches whose name starts with
release/. - CI (
ci.yml) must pass before either workflow can proceed.
- Edit
version.jsonat the repository root:
{
"major": "27",
"minor": "0",
"patch": "0"
}- Commit and push on a
release/branch:
git checkout -b release/MAJOR # e.g. release/27
git add version.json
git commit -m "Bump version to MAJOR.MINOR.PATCH"
git push -u origin release/MAJOR- Wait for CI to pass on that branch.
Trigger the "Create GitHub Release (manual)" workflow:
- Open the workflow in GitHub Actions UI, choose
Run workflow - Set
confirmtotrue - Run on your
release/branch
Or via GitHub CLI:
gh workflow run github-release.yml --ref release/MAJOR -f confirm=trueThis will:
- Ensure CI passed for the commit
- Build the package (
python run.py build) - Create a GitHub Release with tag
vMAJOR.MINOR.PATCH - Attach the wheel (
.whl) and source distribution (.tar.gz) as release assets
The wheel is now available from the GitHub Release assets.
When ready to make the package publicly available, trigger the "Publish to PyPI (manual)" workflow:
- Open the workflow in GitHub Actions UI, choose
Run workflow - Set
tagto the GitHub Release tag (e.g.v27.0.0) - Set
confirmtotrue - Run on your
release/branch
Or via GitHub CLI:
gh workflow run pypi-publish.yml --ref release/MAJOR -f tag=v27.0.0 -f confirm=trueThis will:
- Validate the release tag exists
- Check if the version already exists on PyPI (skip if it does)
- Download the wheel from the GitHub Release assets
- Upload to PyPI using
twine - Build and deploy documentation to GitHub Pages
Creating a GitHub Release does not require older releases to be on PyPI — multiple GitHub Releases can exist during development.
When you run Publish to PyPI, the workflow checks that every older GitHub Release (by version number) is already on PyPI before uploading the tag you selected. Draft and prerelease GitHub Releases are ignored.
Example — GitHub Releases: v26.1.0, v27.0.0, v27.1.0, v27.1.1; PyPI: 26.1.0, 27.0.0:
| Publish tag | Result |
|---|---|
v27.1.0 |
Allowed (older releases are on PyPI) |
v27.1.1 |
Blocked (v27.1.0 is older and not on PyPI) |
Publish in order. If an intermediate build had issues, publish it to PyPI anyway and
follow with the fix — pip install --upgrade resolves to the latest version, so users
are not left on the bad release.
Build the package locally to smoke test:
python run.py buildPublishing to PyPI is restricted to the GitHub Actions workflows. Use --testpypi
for local testing if needed:
python run.py publish --testpypirun.pyrequires apatchvalue in the rootversion.json. It will raise a RuntimeError if that key is missing.- The
run.pyscript writes a package-localsrc/moldflow/version.jsonat build time; you do not need to edit that file directly. - After a successful release and publish, you may merge the
release/branch back tomainand delete the branch.
If anything behaves unexpectedly, check the logs for the github-release and
pypi-publish workflows; feel free to open an issue or ask a maintainer.