In this blog, we will explore how to leverage GitHub Actions for building and releasing tools written in languages such as Go, Python, Rust, and more and this will help you master the process of creating your tools binary releases that meet multi-platform needs.
Prerequisites
Before starting, let’s get ready with the basic setup:
A GitHub repository with Python project (e.g., a tool or CLI app).
Installed Git and set up a local development environment.
A basic understanding of GitHub Actions YAML syntax.
Setting Up Our Python Script
Let’s try to create a simple Python script named hello.py. This will be our example application:
def main():
print("Hello, GitHub Actions!")
if __name__ == "__main__":
main()
Our sample application code is ready, Now, let’s push this to our GitHub repository.
Writing the GitHub Actions Workflow 🔧
Let’s create a directory .github/workflows in the root of our repository and add a file named release.yml. This workflow is triggered whenever we push a new version tag, and it automates the build and release process.
💡
Likewise, GitLab uses the .gitlab-ci.yml file for CI/CD configurations and Bitbucket uses the bitbucket-pipelines.yml file, both typically placed in the root directory of the repository.
Here’s the complete release.yml workflow:
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
name: Release - ${{ matrix.platform.release_for }}
runs-on: ${{ matrix.platform.os }}
strategy:
matrix:
platform:
- release_for: Linux-x86_64
os: ubuntu-latest
pyinstaller_target: linux
bin: hello
name: hello-linux-amd64
- release_for: Windows-x86_64
os: windows-latest
pyinstaller_target: windows
bin: hello.exe
name: hello-windows-amd64.exe
- release_for: macOS-x86_64
os: macos-latest
pyinstaller_target: macos
bin: hello
name: hello-macos-amd64
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install PyInstaller
run: |
python -m pip install --upgrade pip
pip install pyinstaller # Install PyInstaller for packaging
- name: Build Executable
run: |
# Build the executable with PyInstaller for each platform (adjusting accordingly)
pyinstaller --onefile hello.py
working-directory: .
- name: Prepare assets
shell: bash
run: |
# Prepare the release folder
mkdir -p release
cp dist/hello* release/${{ matrix.platform.name }}
- name: Upload binaries to GitHub release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: release/${{ matrix.platform.name }}
asset_name: ${{ matrix.platform.name }}
tag: ${{ github.ref }}
overwrite: true
Create and Push a GitHub Release Tag
For this workflow to trigger, we must create a version tag in this repository. Here’s how to do it via the CLI:
Commit all changes:
git add .
git commit -m "Add release workflow and script"
Create a new version tag:
git tag -a v1.0.0 -m "First release with GitHub Actions"
Push the tag to trigger the workflow:
git push origin --tags
This will start the release workflow in GitHub Actions. we can monitor the progress under the "Actions" tab of our repository.
Now, Let’s understand the workflow 🔍
What Does Each Step Do?
Trigger on Tags
The workflow is triggered when a tag matching the pattern v* is pushed. This ensures it only runs for versioned releases, like in our case we triggered with git tag and pushed the code in repository with tags.
on:
push:
tags:
- 'v*'
Matrix for Multi-Platform Builds
Using matrix.platform, the workflow specifies OS and configuration settings for Linux, macOS, and Windows. For more details about matrix uses, there is an awesome guide from Github
Build with PyInstaller
PyInstaller creates a single executable binary (--onefile option) tailored for each platform.
Package Artifacts for Release
The prepared binaries are moved to a release/ directory with platform-specific names.
Upload Release Assets
The upload-release-action pushes the compiled binaries to the GitHub release, making them available for download.

After the workflow completes:
Navigate to the Releases section of the repository.
Find the latest release created by the workflow.
Download the platform-specific binary from the release assets.
Wrapping Up 🎉
In this article, we demonstrated how to create platform-specific Python executables and automate their release using GitHub Actions. The example release.yml workflow builds, packages, and uploads binaries to GitHub for Windows, macOS, and Linux users seamlessly.
The same strategies in matrix platform can be used for the other language releases as well in order to have the platform specific binaries for your tools. GitHub Actions empowers developers to automate tedious tasks and streamline delivery pipelines, leaving more time for building features and solving user problems. Give it a try and let your tools shine across platforms!
Have feedback or questions? Drop them in the comments!