Automate Build and deploy of Python Package using Github actions.
Tags: github, python, watercooler, devops
Published: 2021-02-13 08:12:25

Are you tired of manually building and deploying Python packages to PyPi. Well here is the solution.

### What you need.
* A github account
* A PyPi account.
* A Packagable Python project.
  * if you dont know how to package a project refer [here](https://packaging.python.org/tutorials/packaging-projects/)

### Lets get started
* Go to the repo containing your python project.
* Click on Actions tab. A window appears.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bnl5b9gpdgxlvj573u3m.png)
* Select the Publish Python package action.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mbsc64vfk9esjv1zwj7j.png)
* Notice that the new file which we are commiting is in the .github folder and inside the workflows folder.
```
.github/workflows/python-publish.yml

```
* Lets see the code which is .yml file containing some commands to be excecuted .
```yaml
name: Upload Python Package

on:
  release:
    types: [created]

jobs:
  deploy:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.x'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install setuptools wheel twine
    - name: Build and publish
      env:
        TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
        TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
      run: |
        python setup.py sdist bdist_wheel
        twine upload dist/*
```  
* Let me explain Line by line.

```yaml
name: Upload Python Package

on:
  release:
    types: [created]
```
* The name : " " is the name of the workflow which you are creating.

* The "on" depicts a event which here is the releases event.
* If we want to run the workflow each time we push code .👇
```yaml
on:
  push:
    branches : [ master ]

```
* Here the event is "Push" so each time you push code the workflow runs.

```yaml
jobs:
 .....
```
* Jobs tells the workflow what all jobs have to be done when the workflow is triggered.

```yaml
deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.x'
```
* runs-on specifies which OS it should run on.
* Then the steps is a long list of works to be done.
* Here the first job is to set up python and the ``` - name ``` means the name of the job running.
* Here is a set of jobs running in my package.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/85sc8fyq00td3pevj4q3.png)

* Then after setting up python we have to install the dependencies.
```yaml
- name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install -r requirements.txt
        pip install setuptools wheel twine
```
* Here the ``` run: | ``` is the set of commands to be executed.
  * We are Upgrading pip.
  * Installing the dependencies in requirements.txt
  * And we are installing setuptools , wheel and twine.
* setuptools and wheel are for packaging.
* Twine is for uploading the package to Pypi.

* Here is the final part to Build and Publish a package.
```yaml
- name: Build and publish
      env:
        TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
        TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
      run: |
        python setup.py sdist bdist_wheel
        twine upload dist/*
``` 

* The ``` env: ``` is some environment variables which you need ( Here your PyPi username and password.)
   * You can go to the repo settings and add secrets , which can be accessed by ```secrets.envname```

* In the "run :" you are seeing two commands.
   * Here ``` python setup.py sdist bdist_wheel ``` builds the package and add it into a dist/ folder.

* And finally " twine upload dist/* " uploads the distributions to PyPi.

* You can also set up tests if you want.

## __Contact__

* Feel free to email [me](mailto:fredysomy@gmail.com) for Bugs Found or queries.
  * [Twitter](https://twitter.com/FredySomy)
  * [Linkedin](https://linkedin.com/in/fredysomy)

* I will be happy to help.
* Cover image taken from [here](https://medium.com/swlh/automate-python-testing-with-github-actions-7926b5d8a865)