with one click
publish
Prepare and publish a release to PyPI and GitHub
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Prepare and publish a release to PyPI and GitHub
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | publish |
| description | Prepare and publish a release to PyPI and GitHub |
Execute the full release workflow for nmaipy.
git branch --show-currentgit status --shortpython -c "from nmaipy import __version__; print(__version__)"gh release list --limit 1 2>/dev/null || echo "No releases found"git describe --tags --abbrev=0 2>/dev/null || echo "No tags found"Execute these steps in order, stopping if any step fails:
Check clean git repo
Check version is new
__version__ with latest GitHub release tagEnforce code formatting
black -l 120 nmaipy/ tests/ and isort nmaipy/ tests/Run test suite (including live API)
pytest (all tests, including live API — requires API_KEY env var) and verify all tests passCode review against last release
git diff $(git describe --tags --abbrev=0)..HEADDetermine release path
git checkout main && git pull so the tag in step 9 lands on the merge commit, not the branch tip.main — never from the feature branch.Build and publish to PyPI
rm -rf dist/ build/ *.egg-infopython -m buildtwine check dist/*twine upload dist/*Write release notes (do this before pushing the tag, so they're ready to apply in step 10)
git log $(git describe --tags --abbrev=0)..HEAD --oneline**bold** for feature names)--generate-notes alone - that only shows commit titlesTag and push
git tag -a vX.Y.Z -m "Release version X.Y.Z"git push origin vX.Y.Z.github/workflows/release.yml), which creates the GitHub release itself (via softprops/action-gh-release) with empty notes and prerelease: false, then attaches the build artifacts. So by step 10 the release usually already exists — you finalize it, you don't create it fresh.Finalize the GitHub release
gh release edit vX.Y.Z --notes-file <notes-file> to apply the step-8 notes.--prerelease here — the workflow defaults the release to prerelease: false, so the flag has to be (re)applied via edit. Plain gh release create --prerelease fails once the workflow has run (HTTP 422: Release.tag_name already exists).gh release create vX.Y.Z --title vX.Y.Z --notes-file <notes-file> [--prerelease].gh release edit vX.Y.Z --notes-file <f> [--prerelease] || gh release create vX.Y.Z --title vX.Y.Z --notes-file <f> [--prerelease].gh release view vX.Y.Z --json isPrerelease,body --jq '{prerelease:.isPrerelease, body_len:(.body|length)}' (body_len > 0; prerelease matches the version).nmaipy is also distributed on conda-forge via the feedstock at
https://github.com/conda-forge/nmaipy-feedstock (recipe: recipe/recipe.yaml,
schema_version: 1 / rattler-build format). This step depends on the PyPI sdist already
being live and does not complete in the same session as the PyPI publish — treat it
as a follow-up to poll for, not a blocking step. Skip it entirely for pre-releases
(versions containing 'a', 'b', or 'rc'): conda-forge tracks stable releases only.
Wait for the autotick bot. Within a few hours of the PyPI release the
regro-cf-autotick-bot opens a version-bump PR on the feedstock that updates only
context.version and source.sha256 (a 2-line change). Find it with:
gh pr list --repo conda-forge/nmaipy-feedstock.
Do not upload to anaconda.org yourself — merging the feedstock PR is what makes
conda-forge CI build the noarch: python package and publish it to the channel.
Reconcile run dependencies — the bot does NOT do this. This is the whole reason the step exists: the bot bumps version + hash only, so a dependency added, removed, or re-floored in nmaipy since the last conda release silently leaves the recipe wrong and the conda package ships with the wrong deps. Compare the two sources of truth:
[project].dependencies in pyproject.tomlrequirements.run in recipe/recipe.yamlgrayskull pypi nmaipy==X.Y.Z regenerates the run list from the published sdist
metadata if you'd rather diff against a fresh generation than eyeball it. If they
differ, push the fix to the bot's PR branch (the bot PR explicitly invites
"Feel free to push to the bot's branch"):
gh repo clone conda-forge/nmaipy-feedstock
cd nmaipy-feedstock && git checkout <bot-branch> # e.g. 5.0.17_h00a991, from the PR
# edit recipe/recipe.yaml requirements.run to match pyproject deps (conda spacing: "name >=x.y")
git commit -am "Sync run requirements with nmaipy X.Y.Z" && git push
The recipe's pip_check: true test fails CI when a declared dep is missing, so a red CI
on the bot PR usually means a run: dep needs adding.
Merge on green CI. You must be a listed maintainer
(extra.recipe-maintainers — currently mbewley, bretttully).
Manual fallback if you can't wait for the bot: branch the feedstock, bump
context.version + source.sha256 (sha256 of the PyPI sdist tarball) and the run-deps
in recipe.yaml, open a PR, merge once CI passes.
Report the final status with links to:
Note: After the tag is pushed, the Release Validation workflow runs automatically: it runs tests, verifies the tag matches the version, creates the GitHub release (empty notes, prerelease: false) and attaches the build artifacts, then verifies the version is live on PyPI (with --pre, so pre-releases are found). Step 10 finalizes the notes and pre-release flag on the release this workflow creates.