Skip to content

Rebuild Python package for PyPi and republish

Louis Maddox edited this page Nov 23, 2020 · 12 revisions

After incrementing the package version number in setup.py, run the following to remove old distribution archives, regenerate them, and then reupload them to PyPi:

EGG_INFO=$(find ./ -iname "*.egg-info");
if [ -d "$EGG_INFO" ]; then
    rm -rf "$EGG_INFO";
fi;
rm -rf build/ dist/;
python3 setup.py sdist bdist_wheel;
python3 -m twine upload dist/*

Source: https://packaging.python.org/tutorials/packaging-projects/

As a convenient one-liner, that first part is:

EGG_INFO=$(find ./ -iname "*.egg-info"); if [ -d "$EGG_INFO" ]; then rm -rf "$EGG_INFO"; fi; rm -rf build/ dist/;

Also note:

  • an API token may be generated (see here)
  • ...and that API token may be saved with keyring (another Python module), preventing you from having to re-enter your credentials each time you reupload

The twine docs explain how to do that here, just run:

keyring set https://upload.pypi.org/legacy/ __token__

and then paste in the API token and you'll save it to your [Python] keyring, and when you run python3 -m twine upload dist/* it'll automatically resolve to that repository URL and since that matches the keyring with username __token__ it won't ask for your credentials and just upload immediately.


I've written some convenience functions to manage the bumping of version numbering, in a workflow that (following a commit/push) goes like so:

tag_new_release_micro "Increment micro version manually via tag"
pypi_republish
  • ...where the part in quotation marks is the tag annotation

There are 3 tag_new_release functions in my .bashrc:

function tag_new_release_micro() {
        eval $(tail -1 version.py | tr -d " " | tr "." ",")
        v_inc=$(python -c "v=[$version]; v[2]+=1; v=map(str,v); print('.'.join(v))")
        git tag -a "v$v_inc" -m "$@"
        git push origin "v$v_inc"
}

function tag_new_release_minor() {
        eval $(tail -1 version.py | tr -d " " | tr "." ",")
        v_inc=$(python -c "v=[$version]; v[1]+=1; v[2]=0; v=map(str,v); print('.'.join(v))")
        git tag -a "v$v_inc" -m "$@"
        git push origin "v$v_inc"
}

function tag_new_release_major() {
        eval $(tail -1 version.py | tr -d " " | tr "." ",")
        v_inc=$(python -c "v=[$version]; v[0]+=1; v[1]=v[2]=0; v=map(str,v); print('.'.join(v))")
        git tag -a "v$v_inc" -m "$@"
        git push origin "v$v_inc"
}

...which bump either the micro, minor, or major part, tag it, then push the tag to GitHub.

Additionally there's one function pypi_republish:

function pypi_republish {
        EGG_INFO=$(find ./ -iname "*.egg-info")
        if [ -d "$EGG_INFO" ]; then rm -rf "$EGG_INFO"; fi
        rm -rf build/ dist/
        python3 setup.py sdist bdist_wheel
        python3 -m twine upload dist/*
}

Clone this wiki locally