Build & Deploy Python package with ease
Tags: python, devops, manylinux, wheel
Published: 2020-07-25 09:26:00

# Manylinux Wheel Builder

We all love python because there is a library in [PyPI](https://pypi.org/) for almost every problem out there but distributing built [wheel](https://pythonwheels.com/) distribution for this libraries haven't been an easy task especially for the Linux. There are many distro built on the GNU/Linux code base and each distro's community makes its own choices about which library versions to include and how long to support them. This is a challenge for someone who just wants to distribute a Python library that contains native C/C++ code. It would be a lot of work to build separate binaries for Red Hat, SUSE, Ubuntu, and Debian—and even more work building separate binaries for each supported Python version!

Fortunately, PyPA's [manylinux](https://github.com/pypa/manylinux) project has come up with a solution that can make a built wheel compatible with most (though not all) Linux distros. They have been releasing docker images that can build this platform independent wheel. So, you can use manylinux docker image to build distro independent wheels but you need to have docker installed on your machine and every time you want to release a new version of your Python library you need to manually build and deploy it on PyPI. To make this process easier for developer, I have created a GitHub action called [manylinux-wheel-builder](https://github.com/marketplace/actions/manylinux-wheel-builder) which will build distro independent wheels and deploy it to PyPI on every push with version releases.

## Basic Usage
If only want to build and publish wheels for Linux platform then below CD action will be enough. It will only build and publish package if pushed commit contains a version tag because this seems the most appropriate in this case but you can change it if you want.
```yml
name: pypi manylinux wheel deployer
on:
  push:
    tags:
      - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
jobs:
  Linux-build:
    runs-on: ubuntu-latest
    env:
      TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
      TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
    steps:
      - uses: actions/checkout@v2
      - name: build and upload manylinux wheels
        uses:  Niraj-Kamdar/manylinux-wheel-builder@master
        # default will be all latest python versions from 3.6+
        # You can specify comma separated string of different python version
        # for which you want to build wheels Ex: "3.6, 3.7" (excludes 3.8 & 3.9)
        with:
          python-versions: "3.*"
```
The secret used in `${{ secrets.TWINE_USERNAME }}` and `${{ secrets.TWINE_PASSWORD }}` needs to be created on the settings page of your project on GitHub. See [Creating & using secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets).

> Pro tip: instead of using branch pointers, like master, pin versions of Actions that you use to tagged versions or sha1 commit identifiers. This will make your workflows more secure and better reproducible, saving you from sudden and unpleasant surprises.

## Advanced Usage
If you also want to build and publish wheels for windows and macos in adition to linux, you can append above action with following yaml snippet. This relies on setup-python action.

```yml
Matrix-build:
    runs-on: ${{ matrix.os }}
    env:
      TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }}
      TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }}
    strategy:
      matrix:
        os: [macos-latest, windows-latest]
        python-version: [3.6, 3.7, 3.8]
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: build wheel
        run: |
          pip install wheel
          python setup.py bdist_wheel
      - name: upload wheel
        run: |
          pip install twine
          twine upload dist/*
        continue-on-error: true
```

Don't forget to see example CD actions from [Examples](https://github.com/Niraj-Kamdar/manylinux-wheel-builder/tree/master/examples).

I hope you like it and use it to build & deploy your python library to PyPI. If you like it don't forget to star my [GitHub repository](https://github.com/Niraj-Kamdar/manylinux-wheel-builder).