Skip to content
Venu's Blog
TwitterGitHub

Continuous Delivery with GitHub Actions

chaoss, grimoirelab, bitergia, github, travis, actions, ci/cd, gha, elasticsearch3 min read

This post would talk discuss how we have set up the Continuous Delivery system using GitHub Actions. This is a continuation post of Continuous Integration with GitHub Actions.

Continuous delivery (CD) is an approach to software engineering based on producing software in short cycles. We want to generate the GrimoireLab releases very frequently but updating all the PyPI images manually is a big task. We wanted to use GitHub Actions to do this job. Whenever a new tag is produced, the project has to be built and published to PyPI.

We were planning to migrate to using Poetry for managing the GrimoireLab project for a long time. Poetry is a tool to handle dependency installation as well as building and packaging Python packages. It makes the tasks simple so, we worked on adding the support for Poetry to all the GrimoireLab tools.

We need to install Poetry, and later we can use the below commands to convert any project to a poetry-based project.

poetry init would initialize a project, you are expected to fill the required fields, and later generates the pyproject.toml file. poetry add package_name would add the package_name as the main dependency, whereas poetry add -D package_name would add the package_name as a developer dependency.

$ poetry init
$ poetry add `cat requirements.txt`
$ poetry add -D `cat requirements_tests.txt`

You can add additional fields which might be needed according to the project like classifiers, packages, license in the pyproject.toml file. You can find the whole list in the documentation, The pyproject.toml file.

Once the pyproject.toml is configured correctly, you can install the project using poetry install. This would create a virtual environment and it can be activated using poetry shell.

$ poetry install
$ poetry shell

We can build the package using poetry build, this would create the wheel and tar packages in the dist folder. Later, we can use poetry publish to publish these wheel packages to PyPI directly. Make sure you have configured the PyPI token accordingly.

$ poetry build
$ poetry publish

Now that we have the required setup and the steps, it is quite easy to create a github actions for publising the packages to PyPI. We created the below github action for the same purpose.

jobs:
build:
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 poetry
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
- name: Build distributions
run: poetry build
- name: Upload distribution artifacts
uses: actions/upload-artifact@v2
with:
name: rt-dist
path: dist
publish:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download distribution artifact
uses: actions/download-artifact@v2
with:
name: rt-dist
path: dist
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install poetry
run: curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
- name: Configure pypi credentials
env:
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: poetry config http-basic.pypi __token__ "$PYPI_API_TOKEN"
- name: Publish release to pypi
run: poetry publish

The action needs to be triggered whenever a release is made. A release tag (eg. 0.1.12) is generated and pushed to the repository whenever the maintainer publishes a release. This can be added as a rule in the github actions.

on:
push:
tags:
- "*.*.*"

We have tested this on a couple of repositories and it worked like a charm. We have some plans to expand this to create a full automatic release workflow system to manage and create releases. I will come up with another blog post soon about it.

~ Venu 👋