Release Python projects with GitHub Actions
Automating repetitive tasks is key to maintaining efficiency and consistency in software development. One such task is packaging and releasing your Python projects. GitHub Actions provides a powerful platform to automate these processes, ensuring that your application is distributed easily and reliably. In this blog post, I’ll show how to set up a GitHub Actions workflow to package and release your Python projects as ZIP artifacts. This is useful to distribute a Python app that would need to run in another system. You could do the same in your local machine using bash scripting and make files but doing so at scale without mistakes would require a pipeline as shown here.
Another option to release your work would be distribute your Python project as a Python package so that others can import the same in their code but that will not be covered in this blog.
Why Automate Releases?
Before diving into the technical details, let’s briefly discuss why automating releases is beneficial:
1. Consistency: Automation ensures that every release follows the same steps, reducing the risk of human error.
2. Efficiency: Once set up, the process requires minimal manual intervention, freeing up time for developers to focus on more critical tasks.
3. Traceability: Automated workflows provide a clear history of releases, making it easier to track changes and debug issues.
Setting Up the GitHub Actions Workflow
Below is a GitHub Actions workflow designed to package and release a Python project. This workflow is triggered whenever a new tag matching the pattern `release-*.*.*` is pushed to the repository.
Workflow Breakdown
name: Create Release
on:
push:
tags:
- 'release-*.*.*'
The workflow is triggered by a push event on tags that follow the `release-*.*.*` pattern. This ensures that releases are only created for specific, versioned tags.
Job Configuration
jobs:
create_release:
runs-on: ubuntu-latest
The job runs on the latest Ubuntu environment, providing a consistent and up-to-date platform for executing the workflow steps.
Steps to Package and Release
1. Checkout the Repository
- name: Checkout repository
uses: actions/checkout@v2
This step checks out the repository, making the code available for subsequent steps.
2. Set Up Python
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.12'
The specified Python version is set up, ensuring compatibility with your project’s requirements.
3. Create Release Directory
- name: Create release directory
run: |
TAG_NAME=${GITHUB_REF##*/}
RELEASE_DIR="release_${TAG_NAME//./_}"
mkdir -p $RELEASE_DIR/credentials
mkdir -p $RELEASE_DIR/resources
A directory structure is created to organize the release files, using the tag name to ensure uniqueness.
4. Copy Files
- name: Copy files
run: |
TAG_NAME=${GITHUB_REF##*/}
RELEASE_DIR="release_${TAG_NAME//./_}"
cp app/python_app/resources/* $RELEASE_DIR/resources/
cp app/python_app/*.py $RELEASE_DIR/
cp app/python_app/requirements.txt $RELEASE_DIR/
The necessary files for the release are copied into the release directory. NOTE: Here it is assumed that you have a folder called python_app within your app folder. The python_app folder additionally contains multiple python files, a requirements.txt file and a folder called resources which can have resources required by your application e.g. images, etc.
5. List Release Directory Contents
- name: List release directory contents
run: |
TAG_NAME=${GITHUB_REF##*/}
RELEASE_DIR="release_${TAG_NAME//./_}"
ls -R $RELEASE_DIR
This step lists the contents of the release directory, providing a quick verification of the files included in the release.
6. Install Zip Utility and Create ZIP File
- name: Install zip utility
run: sudo apt-get install -y zip
- name: Create ZIP file
run: |
TAG_NAME=${GITHUB_REF##*/}
RELEASE_DIR="release_${TAG_NAME//./_}"
zip -r "${RELEASE_DIR}.zip" "$RELEASE_DIR"
The `zip` utility is installed, and the release directory is compressed into a ZIP file for easy distribution.
7. Create GitHub Release
- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
Release notes for ${{ github.ref }}
draft: false
prerelease: false
A new GitHub release is created, using the tag name and including release notes. Please note for this step you would need to provide read and write permissions to the GITHUB_TOKEN. Details on how to provide the same can be found here.
8. Upload Release Asset
- name: Upload release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ env.RELEASE_DIR }}.zip
asset_name: ${{ env.RELEASE_DIR }}.zip
asset_content_type: application/zip
Finally, the ZIP file is uploaded as a release asset, making it available for download from within the Github repository.
Conclusion
By leveraging GitHub Actions, you can automate the packaging and release process for your Python projects, ensuring consistency and efficiency. This workflow provides a solid foundation that you can customize to fit your specific project needs. With automation in place, you can focus more on developing features and less on managing releases.