Automate PyPi releases with Github Actions

Diego Velez
3 min readJun 8, 2022

--

In this article I will show you how to automate your PyPi package releases with Github actions.

This implementation focuses on auto-versioning releases depending on the tag number using semantic versioning (1.0.0, 1.1.0, etc…)

If you just want to to see the code here is the repository with all the needed files https://github.com/Dvelezs94/pypi-auto-release

Goal

We want to create a release on PyPi according to the tag number we push on Github

For this guide I am assuming you already know how to set up a project in PyPi and the basics of Github, I’ll leave some useful links if you have no idea of what I am talking about

Steps

  1. Generate PyPi API token
  2. Store PyPi API token in your Github repository Secrets
  3. Define your setup.py file
  4. Define Github workflow file
  5. Push tags and enjoy

Step by Step

  1. Generate PyPi API token
    For this you will go to PyPi (https://pypi.org/manage/account/) to create an API token, this is so Github can authenticate against PyPi with your user.

2. Store PyPi API token in your Github repository Secrets
Now that you have your PyPi API token, we need to safely store it so Github can fetch it. For that you will need to go to your repository secrets Repository > Settings > Actions > New Repository Secret In here you will name your secret PYPI_API_TOKEN and then paste your PyPi API token

3. Define your setup.py file
Next is to modify your setup.py file to dynamically version your releases The important line is the one with VERSION_PLACEHOLDER string. This string will get updated by Github Actions at run time, so you don’t need to update it every time you make a new release. It will get populated with the value you assign to the tag i.e. 1.0.0, 1.1.1, etc..

"""
Sample setup.py file
"""
from setuptools import setup, find_packages
import codecs
import os

here = os.path.abspath(os.path.dirname(__file__))

with codecs.open(os.path.join(here, "README.md"), encoding="utf-8") as fh:
long_description = "\\n" + fh.read()

setup(
name="my_package_name",
version='{{VERSION_PLACEHOLDER}}',
author="John Doe",
author_email="johndoe@mail.com",
description="my amazing package",
url = "https://github.com/johndoe/my_package",
long_description_content_type="text/markdown",
long_description=long_description,
packages=find_packages(),
install_requires=['numpy'],
keywords=['pypi', 'cicd', 'python'],
classifiers=[
"Development Status :: 1 - Planning",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Operating System :: Unix",
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows"
]
)

4. Define Github workflow file
Just copy and paste the file under repository/.github/workflows/pipy_release.yml
Things you might want to change
- Python version
- Runner (https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners)

name: Publish Python 🐍 distributions 📦 to PyPI

on:
push:
tags:
- '*'

jobs:
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to PyPI
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@master
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: '3.10'
- name: Install pypa/setuptools
run: >-
python -m
pip install wheel
- name: Extract tag name
id: tag
run: echo ::set-output name=TAG_NAME::$(echo $GITHUB_REF | cut -d / -f 3)
- name: Update version in setup.py
run: >-
sed -i "s/{{VERSION_PLACEHOLDER}}/${{ steps.tag.outputs.TAG_NAME }}/g" setup.py
- name: Build a binary wheel
run: >-
python setup.py sdist bdist_wheel
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_API_TOKEN }}

5. Push your code to your main branch and then create a tag by running

git tag 0.0.1 # or whatever version you want 
git push origin --tags

After this you will see Github actions in action (I couldn’t resist) and if everything is correct, you package will get deployed to PyPi (even if its for the first time)

You will be able to see your Github actions runs at repository > actions

Project containing files explained in the tutorial here https://github.com/Dvelezs94/pypi-auto-release

--

--

Diego Velez

Trying to find out what is consciousness and how we can apply it in AI