Skip to content

Commit 25389f3

Browse files
committed
feat: Add a initial version of the action
1 parent 99c1fea commit 25389f3

File tree

3 files changed

+634
-1
lines changed

3 files changed

+634
-1
lines changed

README.md

Lines changed: 214 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,214 @@
1-
# python-binary-action
1+
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/espressif/python-binary-action/master.svg)](https://results.pre-commit.ci/latest/github/espressif/python-binary-action/master)
2+
3+
# Python Binary Build Action
4+
5+
A GitHub Action for building Python applications into standalone executables using `PyInstaller` across multiple architectures and platforms.
6+
7+
## Overview
8+
9+
This action automates the process of creating standalone executables from Python applications using `PyInstaller`. It supports multiple target platforms including Windows, macOS, and Linux (both x86_64 and ARM architectures). The action handles platform-specific configurations, dependency installation, and binary verification automatically.
10+
11+
## Supported Platforms
12+
13+
- **Windows**: `windows-amd64`
14+
- **Linux**: `linux-amd64`, `linux-armv7`, `linux-aarch64`
15+
- **macOS**: `macos-amd64`, `macos-arm64`
16+
17+
## Features
18+
19+
- **Multi-architecture support**: Builds for x86_64 and ARM architectures
20+
- **Cross-platform compatibility**: Supports Windows, macOS, and Linux
21+
- **Automatic dependency handling**: Installs Python dependencies and system packages
22+
- **Flexible data file inclusion**: Supports per-script configuration with wildcard support
23+
- **Binary verification**: Tests built executables to ensure they run correctly
24+
- **Windows icon support**: Allows custom icons for Windows executables
25+
- **Flexible `PyInstaller` configuration**: Supports additional `PyInstaller` arguments
26+
- **ARM cross-compilation**: Uses Public Preview for aarch64 and Docker containers for ARMv7 architecture builds
27+
28+
## Usage Examples
29+
30+
For more detailed explanation of input variables and advanced use cases, please see the [Inputs](#inputs) section below.
31+
32+
### Basic Usage
33+
34+
```yaml
35+
- name: Build Python executable
36+
uses: ./.github/actions/pyinstaller-build-multiarch
37+
with:
38+
scripts: 'main.py'
39+
output-dir: './dist'
40+
target-platform: 'linux-amd64'
41+
```
42+
43+
### Multi-File Build with Data Files
44+
45+
Sometimes your Python script might require additional non-Python files, like asserts (images), JSON or YAML files. These can be included for either all scripts or you can define files per script.
46+
47+
```yaml
48+
- name: Build multiple executables
49+
uses: ./.github/actions/pyinstaller-build-multiarch
50+
with:
51+
scripts: 'app.py utils.py cli.py'
52+
output-dir: './binaries'
53+
target-platform: 'windows-amd64'
54+
include-data-dirs: |
55+
{
56+
"app.py": [{"src": "./assets", "dest": "./assets"}],
57+
"*": [{"src": "./config", "dest": "./config"}]
58+
}
59+
icon-file: './icon.ico'
60+
```
61+
62+
There are two options how to define data files to be included for all scripts:
63+
64+
1. With wildcard `*`
65+
66+
```json
67+
{
68+
"*": [{"src": "./config", "dest": "./config"}]
69+
}
70+
```
71+
72+
2. Simple list
73+
74+
```json
75+
[
76+
{"src": "./config", "dest": "./config"}
77+
]
78+
```
79+
80+
Both options are equivalent, but the wildcard allows you to define additional data files that are specific for one script. As can be seen in the above example for `app.py`.
81+
82+
### Custom Executable Names
83+
84+
```yaml
85+
- name: Build with custom names
86+
uses: ./.github/actions/pyinstaller-build-multiarch
87+
with:
88+
scripts: 'my_script/__main__.py'
89+
script-name: 'my_script'
90+
output-dir: './dist'
91+
target-platform: 'linux-amd64'
92+
```
93+
94+
This will create executable named `my_script` instead of `__main__.py`.
95+
96+
### ARM Architecture Build
97+
98+
```yaml
99+
- name: Build for ARMv7
100+
uses: ./.github/actions/pyinstaller-build-multiarch
101+
with:
102+
scripts: 'main.py'
103+
output-dir: './arm-binaries'
104+
target-platform: 'linux-armv7'
105+
additional-arm-packages: 'openssl libffi-dev libffi7 libssl-dev'
106+
python-version: '3.11'
107+
```
108+
109+
### Custom PyInstaller Configuration
110+
111+
```yaml
112+
- name: Build with custom options
113+
uses: ./.github/actions/pyinstaller-build-multiarch
114+
with:
115+
scripts: 'app.py'
116+
output-dir: './dist'
117+
target-platform: 'macos-arm64'
118+
additional-args: '--hidden-import=requests --hidden-import=urllib3 --strip'
119+
pyinstaller-version: '6.3.0'
120+
test-command-args: '--version'
121+
```
122+
123+
### Complete Workflow Example
124+
125+
```yaml
126+
name: Build Executables
127+
128+
on: [push, pull_request]
129+
130+
jobs:
131+
build:
132+
runs-on: ubuntu-latest
133+
strategy:
134+
fail-fast: false
135+
matrix:
136+
platform: [windows-amd64, linux-amd64, macos-arm64]
137+
138+
env:
139+
STUBS_DIR: ./esptool/targets/stub_flasher/
140+
141+
steps:
142+
- name: Checkout code
143+
uses: actions/checkout@v4
144+
145+
- name: Set up Python
146+
uses: actions/setup-python@v5
147+
with:
148+
python-version: '3.11'
149+
150+
- name: Build executable
151+
uses: ./.github/actions/pyinstaller-build-multiarch
152+
with:
153+
scripts: 'esptool.py'
154+
output-dir: './dist-${{ matrix.platform }}'
155+
target-platform: ${{ matrix.platform }}
156+
include-data-dirs: |
157+
{
158+
"epstool.py": [
159+
{"src": "${{ env.STUBS_DIR }}1", "dest": "${{ env.STUBS_DIR }}1"},
160+
{"src": "${{ env.STUBS_DIR }}2", "dest": "${{ env.STUBS_DIR }}2"},
161+
]
162+
}
163+
164+
- name: Add license and readme
165+
shell: bash
166+
run: mv LICENSE README.md ./dist-${{ matrix.platform }}
167+
168+
- name: Upload artifacts
169+
uses: actions/upload-artifact@v4
170+
with:
171+
name: executable-${{ matrix.platform }}
172+
path: ./dist-${{ matrix.platform }}
173+
```
174+
175+
## Inputs
176+
177+
### Required Inputs
178+
179+
| Input | Description | Example |
180+
|-------------------|-----------------------------------------------|----------------------------|
181+
| `scripts` | Space-separated list of Python files to build | `"main.py utils.py"` |
182+
| `output-dir` | Output directory for built executables | `"./dist-linux-amd64"` |
183+
| `target-platform` | Target platform for the build | `"linux-amd64"` |
184+
185+
### Optional Inputs
186+
187+
| Input | Description | Default | Example |
188+
|---------------------------|-------------------------------------------|---------------------------------------------|-----------------------------------------|
189+
| `script-name` | Executable names. Must match the length of `scripts`. If not provided, the script name will be used. | `""` | `"foo bar"` |
190+
| `include-data-dirs` | Mapping script names to data directories to include. Supports wildcards (*). | `[]` | `{"main.py": [{"src": "./data", "dest": "./data"}], "*": [{"src": "./common", "dest": "./common"}]}` |
191+
| `icon-file` | Path to icon file (Windows only) | `""` | `"./icon.ico"` |
192+
| `python-version` | Python version to use | `"3.13"` | `"3.12"` |
193+
| `pyinstaller-version` | PyInstaller version to install | `"6.11.1"` | `"latest"` |
194+
| `additional-args` | Additional PyInstaller arguments | `""` | `"--hidden-import=module"` |
195+
| `pip-extra-index-url` | Extra pip index URL | `"https://dl.espressif.com/pypi"` | `""` |
196+
| `install-deps-command` | Command to install project dependencies | `"pip install --user --prefer-binary -e ."` | `"pip install -r requirements.txt"` |
197+
| `additional-arm-packages` | ARMv7 ONLY: Additional system packages | `""` | `"openssl libffi-dev"` |
198+
| `test-command-args` | Command arguments to test binaries | `"--help"` | `"--version"` |
199+
200+
## Outputs
201+
202+
| Output | Description |
203+
|------------------------|----------------------------------------------------------------|
204+
| `executable-extension` | File extension of built executables (e.g., `.exe` for Windows) |
205+
| `build-success` | Whether the build was successful (`true`/`false`) |
206+
207+
## Notes
208+
209+
- For 32-bit ARM architecture (linux-armv7), the action uses Docker containers to provide the necessary build environment
210+
- For 64-bit ARM architecture please use the GitHub provided runners, e.g. `ubuntu-22.04-arm`. Please note that this is still in public preview so there might be some changes to images. For more details see [available runners](https://docs.github.com/en/actions/how-tos/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources).
211+
- Windows builds automatically include `.exe` extensions
212+
- The action automatically tests built executables using the specified test command arguments
213+
- System packages for ARMv7 builds can be customized using the `additional-arm-packages` input. For other systems, this can be done before running this action.
214+
- It is recommended to add `fail-fast: false` to your matrix strategy to prevent one platform failure from stopping all builds

0 commit comments

Comments
 (0)